From c185e482e9bfee7fc1c0c3c9b5f58ca64d968349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Fri, 1 May 2020 11:20:58 +0300 Subject: Document Gnome Builder support --- docs/user/readme.adoc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/user/readme.adoc b/docs/user/readme.adoc index 4cb1e23e8..b1af72ce6 100644 --- a/docs/user/readme.adoc +++ b/docs/user/readme.adoc @@ -201,7 +201,7 @@ let g:LanguageClient_serverCommands = { 2. Configure by adding this to your vim/neovim config file (replacing the existing Rust-specific line if it exists): + -[source,vim] +[source,vim] ---- let g:ycm_language_server = \ [ @@ -252,6 +252,15 @@ If it worked, you should see "rust-analyzer, Line X, Column Y" on the left side If you get an error saying `No such file or directory: 'rust-analyzer'`, see the <> section on installing the language server binary. +=== Gnome Builder + +Prerequisites: You have installed the <>. + +Gnome Builder currently has support for RLS, and there's no way to configure the language server executable. A future version might support `rust-analyzer` out of the box. + +1. Rename, symlink or copy the `rust-analyzer` binary to `rls` and place it somewhere Builder can find (in `PATH`, or under `~/.cargo/bin`). +2. Enable the Rust Builder plugin. + == Usage See https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/features.md[features.md]. -- cgit v1.2.3 From 1635d22a355b08309661e3d54d22c6bc2b53e5e1 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Thu, 30 Apr 2020 18:12:52 +0800 Subject: Add test --- crates/ra_hir_ty/src/tests/macros.rs | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs index 5ddecbdc6..1f796876d 100644 --- a/crates/ra_hir_ty/src/tests/macros.rs +++ b/crates/ra_hir_ty/src/tests/macros.rs @@ -338,6 +338,46 @@ pub fn baz() -> usize { 31usize } assert_eq!("(i32, usize)", type_at_pos(&db, pos)); } +#[test] +fn infer_macro_with_dollar_crate_is_correct_in_trait_associate_type() { + let (db, pos) = TestDB::with_position( + r#" +//- /main.rs crate:main deps:foo +use foo::Trait; + +fn test() { + let msg = foo::Message(foo::MessageRef); + let r = msg.deref(); + r<|>; +} + +//- /lib.rs crate:foo +pub struct MessageRef; +pub struct Message(MessageRef); + +pub trait Trait { + type Target; + fn deref(&self) -> &Self::Target; +} + +#[macro_export] +macro_rules! expand { + () => { + impl Trait for Message { + type Target = $crate::MessageRef; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + } +} + +expand!(); +"#, + ); + assert_eq!("&MessageRef", type_at_pos(&db, pos)); +} + #[test] fn infer_type_value_non_legacy_macro_use_as() { assert_snapshot!( -- cgit v1.2.3 From bdcf6f56589f8367c8cc82f3f4f045dcaf53748d Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Thu, 30 Apr 2020 18:20:13 +0800 Subject: Introduce LowerCtx for path lowering --- crates/ra_assists/src/assist_ctx.rs | 9 ++- crates/ra_assists/src/ast_transform.rs | 2 + .../handlers/replace_qualified_name_with_use.rs | 2 +- crates/ra_hir/src/lib.rs | 3 +- crates/ra_hir/src/source_analyzer.rs | 3 +- crates/ra_hir_def/src/adt.rs | 18 ++++-- crates/ra_hir_def/src/body.rs | 2 + crates/ra_hir_def/src/body/lower.rs | 42 ++++++++++--- crates/ra_hir_def/src/data.rs | 21 ++++--- crates/ra_hir_def/src/generics.rs | 68 +++++++++++++++------- crates/ra_hir_def/src/path.rs | 5 +- crates/ra_hir_def/src/path/lower.rs | 23 +++++--- crates/ra_hir_def/src/type_ref.rs | 52 ++++++++++------- crates/ra_hir_expand/src/hygiene.rs | 2 +- 14 files changed, 172 insertions(+), 80 deletions(-) diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs index 2fe7c3de3..3155a469b 100644 --- a/crates/ra_assists/src/assist_ctx.rs +++ b/crates/ra_assists/src/assist_ctx.rs @@ -1,12 +1,12 @@ //! This module defines `AssistCtx` -- the API surface that is exposed to assists. use hir::Semantics; -use ra_db::FileRange; +use ra_db::{FileRange, Upcast}; use ra_fmt::{leading_indent, reindent}; use ra_ide_db::RootDatabase; use ra_syntax::{ algo::{self, find_covering_element, find_node_at_offset}, - AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize, - TokenAtOffset, + ast, AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, + TextSize, TokenAtOffset, }; use ra_text_edit::TextEditBuilder; @@ -136,6 +136,9 @@ impl<'a> AssistCtx<'a> { pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement { find_covering_element(self.source_file.syntax(), range) } + pub(crate) fn lower_path(&self, path: ast::Path) -> Option { + hir::Path::from_src(path, &hir::Hygiene::new(self.db.upcast(), self.frange.file_id.into())) + } } pub(crate) struct AssistGroup<'a> { diff --git a/crates/ra_assists/src/ast_transform.rs b/crates/ra_assists/src/ast_transform.rs index 52b4c82db..9ac65ab39 100644 --- a/crates/ra_assists/src/ast_transform.rs +++ b/crates/ra_assists/src/ast_transform.rs @@ -85,6 +85,7 @@ impl<'a> SubstituteTypeParams<'a> { ast::TypeRef::PathType(path_type) => path_type.path()?, _ => return None, }; + // FIXME: use `hir::Path::from_src` instead. let path = hir::Path::from_ast(path)?; let resolution = self.source_scope.resolve_hir_path(&path)?; match resolution { @@ -128,6 +129,7 @@ impl<'a> QualifyPaths<'a> { // don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway return None; } + // FIXME: use `hir::Path::from_src` instead. let hir_path = hir::Path::from_ast(p.clone()); let resolution = self.source_scope.resolve_hir_path(&hir_path?)?; match resolution { diff --git a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs index 2f02df303..ad59db392 100644 --- a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs +++ b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs @@ -27,7 +27,7 @@ pub(crate) fn replace_qualified_name_with_use(ctx: AssistCtx) -> Option return None; } - let hir_path = hir::Path::from_ast(path.clone())?; + let hir_path = ctx.lower_path(path.clone())?; let segments = collect_hir_path_segments(&hir_path)?; if segments.len() < 2 { return None; diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 312ef3814..c5df4ac24 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -70,6 +70,7 @@ pub use hir_def::{ type_ref::Mutability, }; pub use hir_expand::{ - name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Origin, + hygiene::Hygiene, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, + MacroFile, Origin, }; pub use hir_ty::{display::HirDisplay, CallableDef}; diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs index 74d64c97d..c63d1b847 100644 --- a/crates/ra_hir/src/source_analyzer.rs +++ b/crates/ra_hir/src/source_analyzer.rs @@ -224,7 +224,8 @@ impl SourceAnalyzer { } } // This must be a normal source file rather than macro file. - let hir_path = crate::Path::from_ast(path.clone())?; + let hir_path = + crate::Path::from_src(path.clone(), &Hygiene::new(db.upcast(), self.file_id))?; resolve_hir_path(db, &self.resolver, &hir_path) } diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 753becc3d..8eef51828 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -12,9 +12,15 @@ use ra_prof::profile; use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner}; use crate::{ - body::CfgExpander, db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, - type_ref::TypeRef, visibility::RawVisibility, EnumId, HasModule, LocalEnumVariantId, - LocalFieldId, Lookup, ModuleId, StructId, UnionId, VariantId, + body::{CfgExpander, LowerCtx}, + db::DefDatabase, + src::HasChildSource, + src::HasSource, + trace::Trace, + type_ref::TypeRef, + visibility::RawVisibility, + EnumId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId, + VariantId, }; /// Note that we use `StructData` for unions as well! @@ -198,6 +204,8 @@ fn lower_struct( trace: &mut Trace>, ast: &InFile, ) -> StructKind { + let ctx = LowerCtx::new(db, ast.file_id); + match &ast.value { ast::StructKind::Tuple(fl) => { for (i, fd) in fl.fields().enumerate() { @@ -210,7 +218,7 @@ fn lower_struct( || Either::Left(fd.clone()), || FieldData { name: Name::new_tuple_field(i), - type_ref: TypeRef::from_ast_opt(fd.type_ref()), + type_ref: TypeRef::from_ast_opt(&ctx, fd.type_ref()), visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())), }, ); @@ -228,7 +236,7 @@ fn lower_struct( || Either::Right(fd.clone()), || FieldData { name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing), - type_ref: TypeRef::from_ast_opt(fd.ascribed_type()), + type_ref: TypeRef::from_ast_opt(&ctx, fd.ascribed_type()), visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())), }, ); diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 890cefcaf..4edaad960 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -15,6 +15,8 @@ use ra_prof::profile; use ra_syntax::{ast, AstNode, AstPtr}; use rustc_hash::FxHashMap; +pub(crate) use lower::LowerCtx; + use crate::{ attr::Attrs, db::DefDatabase, diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index f467ed3fe..e9dd65b0a 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -3,8 +3,9 @@ use either::Either; use hir_expand::{ + hygiene::Hygiene, name::{name, AsName, Name}, - MacroDefId, MacroDefKind, + HirFileId, MacroDefId, MacroDefKind, }; use ra_arena::Arena; use ra_syntax::{ @@ -26,7 +27,7 @@ use crate::{ LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, }, item_scope::BuiltinShadowMode, - path::GenericArgs, + path::{GenericArgs, Path}, type_ref::{Mutability, TypeRef}, AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, @@ -35,6 +36,23 @@ use crate::{ use super::{ExprSource, PatSource}; use ast::AstChildren; +pub(crate) struct LowerCtx { + hygiene: Hygiene, +} + +impl LowerCtx { + pub fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self { + LowerCtx { hygiene: Hygiene::new(db.upcast(), file_id) } + } + pub fn with_hygiene(hygiene: &Hygiene) -> Self { + LowerCtx { hygiene: hygiene.clone() } + } + + pub fn lower_path(&self, ast: ast::Path) -> Option { + Path::from_src(ast, &self.hygiene) + } +} + pub(super) fn lower( db: &dyn DefDatabase, def: DefWithBodyId, @@ -42,10 +60,13 @@ pub(super) fn lower( params: Option, body: Option, ) -> (Body, BodySourceMap) { + let ctx = LowerCtx::new(db, expander.current_file_id.clone()); + ExprCollector { db, def, expander, + ctx, source_map: BodySourceMap::default(), body: Body { exprs: Arena::default(), @@ -62,7 +83,7 @@ struct ExprCollector<'a> { db: &'a dyn DefDatabase, def: DefWithBodyId, expander: Expander, - + ctx: LowerCtx, body: Body, source_map: BodySourceMap, } @@ -237,7 +258,8 @@ impl ExprCollector<'_> { Vec::new() }; let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); - let generic_args = e.type_arg_list().and_then(GenericArgs::from_ast); + let generic_args = + e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx, it)); self.alloc_expr( Expr::MethodCall { receiver, method_name, args, generic_args }, syntax_ptr, @@ -343,7 +365,7 @@ impl ExprCollector<'_> { } ast::Expr::CastExpr(e) => { let expr = self.collect_expr_opt(e.expr()); - let type_ref = TypeRef::from_ast_opt(e.type_ref()); + let type_ref = TypeRef::from_ast_opt(&self.ctx, e.type_ref()); self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) } ast::Expr::RefExpr(e) => { @@ -365,12 +387,16 @@ impl ExprCollector<'_> { if let Some(pl) = e.param_list() { for param in pl.params() { let pat = self.collect_pat_opt(param.pat()); - let type_ref = param.ascribed_type().map(TypeRef::from_ast); + let type_ref = + param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); args.push(pat); arg_types.push(type_ref); } } - let ret_type = e.ret_type().and_then(|r| r.type_ref()).map(TypeRef::from_ast); + let ret_type = e + .ret_type() + .and_then(|r| r.type_ref()) + .map(|it| TypeRef::from_ast(&self.ctx, it)); let body = self.collect_expr_opt(e.body()); self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) } @@ -476,7 +502,7 @@ impl ExprCollector<'_> { .map(|s| match s { ast::Stmt::LetStmt(stmt) => { let pat = self.collect_pat_opt(stmt.pat()); - let type_ref = stmt.ascribed_type().map(TypeRef::from_ast); + let type_ref = stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); let initializer = stmt.initializer().map(|e| self.collect_expr(e)); Statement::Let { pat, type_ref, initializer } } diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index ccb682f9a..7a2067e49 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -15,6 +15,7 @@ use ra_syntax::ast::{ use crate::{ attr::Attrs, + body::LowerCtx, db::DefDatabase, path::{path, AssociatedTypeBinding, GenericArgs, Path}, src::HasSource, @@ -40,13 +41,14 @@ impl FunctionData { pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc { let loc = func.lookup(db); let src = loc.source(db); + let ctx = LowerCtx::new(db, src.file_id); let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); let mut params = Vec::new(); let mut has_self_param = false; if let Some(param_list) = src.value.param_list() { if let Some(self_param) = param_list.self_param() { let self_type = if let Some(type_ref) = self_param.ascribed_type() { - TypeRef::from_ast(type_ref) + TypeRef::from_ast(&ctx, type_ref) } else { let self_type = TypeRef::Path(name![Self].into()); match self_param.kind() { @@ -63,14 +65,14 @@ impl FunctionData { has_self_param = true; } for param in param_list.params() { - let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); + let type_ref = TypeRef::from_ast_opt(&ctx, param.ascribed_type()); params.push(type_ref); } } let attrs = Attrs::new(&src.value, &Hygiene::new(db.upcast(), src.file_id)); let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { - TypeRef::from_ast(type_ref) + TypeRef::from_ast(&ctx, type_ref) } else { TypeRef::unit() }; @@ -122,7 +124,8 @@ impl TypeAliasData { let loc = typ.lookup(db); let node = loc.source(db); let name = node.value.name().map_or_else(Name::missing, |n| n.as_name()); - let type_ref = node.value.type_ref().map(TypeRef::from_ast); + let lower_ctx = LowerCtx::new(db, node.file_id); + let type_ref = node.value.type_ref().map(|it| TypeRef::from_ast(&lower_ctx, it)); let vis_default = RawVisibility::default_for_container(loc.container); let visibility = RawVisibility::from_ast_with_default( db, @@ -130,7 +133,7 @@ impl TypeAliasData { node.as_ref().map(|n| n.visibility()), ); let bounds = if let Some(bound_list) = node.value.type_bound_list() { - bound_list.bounds().map(TypeBound::from_ast).collect() + bound_list.bounds().map(|it| TypeBound::from_ast(&lower_ctx, it)).collect() } else { Vec::new() }; @@ -223,9 +226,10 @@ impl ImplData { let _p = profile("impl_data_query"); let impl_loc = id.lookup(db); let src = impl_loc.source(db); + let lower_ctx = LowerCtx::new(db, src.file_id); - let target_trait = src.value.target_trait().map(TypeRef::from_ast); - let target_type = TypeRef::from_ast_opt(src.value.target_type()); + let target_trait = src.value.target_trait().map(|it| TypeRef::from_ast(&lower_ctx, it)); + let target_type = TypeRef::from_ast_opt(&lower_ctx, src.value.target_type()); let is_negative = src.value.excl_token().is_some(); let module_id = impl_loc.container.module(db); @@ -279,8 +283,9 @@ impl ConstData { vis_default: RawVisibility, node: InFile, ) -> ConstData { + let ctx = LowerCtx::new(db, node.file_id); let name = node.value.name().map(|n| n.as_name()); - let type_ref = TypeRef::from_ast_opt(node.value.ascribed_type()); + let type_ref = TypeRef::from_ast_opt(&ctx, node.value.ascribed_type()); let visibility = RawVisibility::from_ast_with_default(db, vis_default, node.map(|n| n.visibility())); ConstData { name, type_ref, visibility } diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index d850244c4..09a5241f7 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -15,6 +15,7 @@ use ra_prof::profile; use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; use crate::{ + body::LowerCtx, child_by_source::ChildBySource, db::DefDatabase, dyn_map::DynMap, @@ -80,11 +81,13 @@ impl GenericParams { fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile) { let mut generics = GenericParams { types: Arena::default(), where_predicates: Vec::new() }; let mut sm = ArenaMap::default(); + // FIXME: add `: Sized` bound for everything except for `Self` in traits let file_id = match def { GenericDefId::FunctionId(it) => { let src = it.lookup(db).source(db); - generics.fill(&mut sm, &src.value); + let lower_ctx = LowerCtx::new(db, src.file_id); + generics.fill(&lower_ctx, &mut sm, &src.value); // lower `impl Trait` in arguments let data = db.function_data(it); for param in &data.params { @@ -94,21 +97,25 @@ impl GenericParams { } GenericDefId::AdtId(AdtId::StructId(it)) => { let src = it.lookup(db).source(db); - generics.fill(&mut sm, &src.value); + let lower_ctx = LowerCtx::new(db, src.file_id); + generics.fill(&lower_ctx, &mut sm, &src.value); src.file_id } GenericDefId::AdtId(AdtId::UnionId(it)) => { let src = it.lookup(db).source(db); - generics.fill(&mut sm, &src.value); + let lower_ctx = LowerCtx::new(db, src.file_id); + generics.fill(&lower_ctx, &mut sm, &src.value); src.file_id } GenericDefId::AdtId(AdtId::EnumId(it)) => { let src = it.lookup(db).source(db); - generics.fill(&mut sm, &src.value); + let lower_ctx = LowerCtx::new(db, src.file_id); + generics.fill(&lower_ctx, &mut sm, &src.value); src.file_id } GenericDefId::TraitId(it) => { let src = it.lookup(db).source(db); + let lower_ctx = LowerCtx::new(db, src.file_id); // traits get the Self type as an implicit first type parameter let self_param_id = generics.types.alloc(TypeParamData { @@ -120,14 +127,16 @@ impl GenericParams { // add super traits as bounds on Self // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar let self_param = TypeRef::Path(name![Self].into()); - generics.fill_bounds(&src.value, self_param); + generics.fill_bounds(&lower_ctx, &src.value, self_param); - generics.fill(&mut sm, &src.value); + generics.fill(&lower_ctx, &mut sm, &src.value); src.file_id } GenericDefId::TypeAliasId(it) => { let src = it.lookup(db).source(db); - generics.fill(&mut sm, &src.value); + let lower_ctx = LowerCtx::new(db, src.file_id); + + generics.fill(&lower_ctx, &mut sm, &src.value); src.file_id } // Note that we don't add `Self` here: in `impl`s, `Self` is not a @@ -135,7 +144,9 @@ impl GenericParams { // type, so this is handled by the resolver. GenericDefId::ImplId(it) => { let src = it.lookup(db).source(db); - generics.fill(&mut sm, &src.value); + let lower_ctx = LowerCtx::new(db, src.file_id); + + generics.fill(&lower_ctx, &mut sm, &src.value); src.file_id } // We won't be using this ID anyway @@ -145,28 +156,38 @@ impl GenericParams { (generics, InFile::new(file_id, sm)) } - fn fill(&mut self, sm: &mut SourceMap, node: &dyn TypeParamsOwner) { + fn fill(&mut self, lower_ctx: &LowerCtx, sm: &mut SourceMap, node: &dyn TypeParamsOwner) { if let Some(params) = node.type_param_list() { - self.fill_params(sm, params) + self.fill_params(lower_ctx, sm, params) } if let Some(where_clause) = node.where_clause() { - self.fill_where_predicates(where_clause); + self.fill_where_predicates(lower_ctx, where_clause); } } - fn fill_bounds(&mut self, node: &dyn ast::TypeBoundsOwner, type_ref: TypeRef) { + fn fill_bounds( + &mut self, + lower_ctx: &LowerCtx, + node: &dyn ast::TypeBoundsOwner, + type_ref: TypeRef, + ) { for bound in node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) { - self.add_where_predicate_from_bound(bound, type_ref.clone()); + self.add_where_predicate_from_bound(lower_ctx, bound, type_ref.clone()); } } - fn fill_params(&mut self, sm: &mut SourceMap, params: ast::TypeParamList) { + fn fill_params( + &mut self, + lower_ctx: &LowerCtx, + sm: &mut SourceMap, + params: ast::TypeParamList, + ) { for type_param in params.type_params() { let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); // FIXME: Use `Path::from_src` - let default = type_param.default_type().map(TypeRef::from_ast); + let default = type_param.default_type().map(|it| TypeRef::from_ast(lower_ctx, it)); let param = TypeParamData { name: Some(name.clone()), default, @@ -176,29 +197,34 @@ impl GenericParams { sm.insert(param_id, Either::Right(type_param.clone())); let type_ref = TypeRef::Path(name.into()); - self.fill_bounds(&type_param, type_ref); + self.fill_bounds(&lower_ctx, &type_param, type_ref); } } - fn fill_where_predicates(&mut self, where_clause: ast::WhereClause) { + fn fill_where_predicates(&mut self, lower_ctx: &LowerCtx, where_clause: ast::WhereClause) { for pred in where_clause.predicates() { let type_ref = match pred.type_ref() { Some(type_ref) => type_ref, None => continue, }; - let type_ref = TypeRef::from_ast(type_ref); + let type_ref = TypeRef::from_ast(lower_ctx, type_ref); for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { - self.add_where_predicate_from_bound(bound, type_ref.clone()); + self.add_where_predicate_from_bound(lower_ctx, bound, type_ref.clone()); } } } - fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) { + fn add_where_predicate_from_bound( + &mut self, + lower_ctx: &LowerCtx, + bound: ast::TypeBound, + type_ref: TypeRef, + ) { if bound.question_token().is_some() { // FIXME: remove this bound return; } - let bound = TypeBound::from_ast(bound); + let bound = TypeBound::from_ast(lower_ctx, bound); self.where_predicates .push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound }); } diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 162b3c8c7..e84efe2ab 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -7,6 +7,7 @@ use std::{ sync::Arc, }; +use crate::body::LowerCtx; use hir_expand::{ hygiene::Hygiene, name::{AsName, Name}, @@ -244,8 +245,8 @@ impl<'a> PathSegments<'a> { } impl GenericArgs { - pub(crate) fn from_ast(node: ast::TypeArgList) -> Option { - lower::lower_generic_args(node) + pub(crate) fn from_ast(lower_ctx: &LowerCtx, node: ast::TypeArgList) -> Option { + lower::lower_generic_args(lower_ctx, node) } pub(crate) fn empty() -> GenericArgs { diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs index 9ec2e0dcd..e3d237a0a 100644 --- a/crates/ra_hir_def/src/path/lower.rs +++ b/crates/ra_hir_def/src/path/lower.rs @@ -13,6 +13,7 @@ use ra_syntax::ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner}; use super::AssociatedTypeBinding; use crate::{ + body::LowerCtx, path::{GenericArg, GenericArgs, ModPath, Path, PathKind}, type_ref::{TypeBound, TypeRef}, }; @@ -26,6 +27,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option let mut type_anchor = None; let mut segments = Vec::new(); let mut generic_args = Vec::new(); + let ctx = LowerCtx::with_hygiene(hygiene); loop { let segment = path.segment()?; @@ -40,9 +42,10 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option Either::Left(name) => { let args = segment .type_arg_list() - .and_then(lower_generic_args) + .and_then(|it| lower_generic_args(&ctx, it)) .or_else(|| { lower_generic_args_from_fn_path( + &ctx, segment.param_list(), segment.ret_type(), ) @@ -60,7 +63,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option ast::PathSegmentKind::Type { type_ref, trait_ref } => { assert!(path.qualifier().is_none()); // this can only occur at the first segment - let self_type = TypeRef::from_ast(type_ref?); + let self_type = TypeRef::from_ast(&ctx, type_ref?); match trait_ref { // ::foo @@ -128,10 +131,13 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option } } -pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option { +pub(super) fn lower_generic_args( + lower_ctx: &LowerCtx, + node: ast::TypeArgList, +) -> Option { let mut args = Vec::new(); for type_arg in node.type_args() { - let type_ref = TypeRef::from_ast_opt(type_arg.type_ref()); + let type_ref = TypeRef::from_ast_opt(lower_ctx, type_arg.type_ref()); args.push(GenericArg::Type(type_ref)); } // lifetimes ignored for now @@ -140,9 +146,9 @@ pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg; if let Some(name_ref) = assoc_type_arg.name_ref() { let name = name_ref.as_name(); - let type_ref = assoc_type_arg.type_ref().map(TypeRef::from_ast); + let type_ref = assoc_type_arg.type_ref().map(|it| TypeRef::from_ast(lower_ctx, it)); let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { - l.bounds().map(TypeBound::from_ast).collect() + l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect() } else { Vec::new() }; @@ -159,6 +165,7 @@ pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option /// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) /// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). fn lower_generic_args_from_fn_path( + ctx: &LowerCtx, params: Option, ret_type: Option, ) -> Option { @@ -167,14 +174,14 @@ fn lower_generic_args_from_fn_path( if let Some(params) = params { let mut param_types = Vec::new(); for param in params.params() { - let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); + let type_ref = TypeRef::from_ast_opt(&ctx, param.ascribed_type()); param_types.push(type_ref); } let arg = GenericArg::Type(TypeRef::Tuple(param_types)); args.push(arg); } if let Some(ret_type) = ret_type { - let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); + let type_ref = TypeRef::from_ast_opt(&ctx, ret_type.type_ref()); bindings.push(AssociatedTypeBinding { name: name![Output], type_ref: Some(type_ref), diff --git a/crates/ra_hir_def/src/type_ref.rs b/crates/ra_hir_def/src/type_ref.rs index f308c6bdf..5bdad9efd 100644 --- a/crates/ra_hir_def/src/type_ref.rs +++ b/crates/ra_hir_def/src/type_ref.rs @@ -3,7 +3,7 @@ use ra_syntax::ast::{self, TypeAscriptionOwner, TypeBoundsOwner}; -use crate::path::Path; +use crate::{body::LowerCtx, path::Path}; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum Mutability { @@ -64,30 +64,34 @@ pub enum TypeBound { impl TypeRef { /// Converts an `ast::TypeRef` to a `hir::TypeRef`. - pub(crate) fn from_ast(node: ast::TypeRef) -> Self { + pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::TypeRef) -> Self { match node { - ast::TypeRef::ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()), + ast::TypeRef::ParenType(inner) => TypeRef::from_ast_opt(&ctx, inner.type_ref()), ast::TypeRef::TupleType(inner) => { - TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()) + TypeRef::Tuple(inner.fields().map(|it| TypeRef::from_ast(ctx, it)).collect()) } ast::TypeRef::NeverType(..) => TypeRef::Never, ast::TypeRef::PathType(inner) => { // FIXME: Use `Path::from_src` - inner.path().and_then(Path::from_ast).map(TypeRef::Path).unwrap_or(TypeRef::Error) + inner + .path() + .and_then(|it| ctx.lower_path(it)) + .map(TypeRef::Path) + .unwrap_or(TypeRef::Error) } ast::TypeRef::PointerType(inner) => { - let inner_ty = TypeRef::from_ast_opt(inner.type_ref()); + let inner_ty = TypeRef::from_ast_opt(&ctx, inner.type_ref()); let mutability = Mutability::from_mutable(inner.mut_token().is_some()); TypeRef::RawPtr(Box::new(inner_ty), mutability) } ast::TypeRef::ArrayType(inner) => { - TypeRef::Array(Box::new(TypeRef::from_ast_opt(inner.type_ref()))) + TypeRef::Array(Box::new(TypeRef::from_ast_opt(&ctx, inner.type_ref()))) } ast::TypeRef::SliceType(inner) => { - TypeRef::Slice(Box::new(TypeRef::from_ast_opt(inner.type_ref()))) + TypeRef::Slice(Box::new(TypeRef::from_ast_opt(&ctx, inner.type_ref()))) } ast::TypeRef::ReferenceType(inner) => { - let inner_ty = TypeRef::from_ast_opt(inner.type_ref()); + let inner_ty = TypeRef::from_ast_opt(&ctx, inner.type_ref()); let mutability = Mutability::from_mutable(inner.mut_token().is_some()); TypeRef::Reference(Box::new(inner_ty), mutability) } @@ -96,10 +100,13 @@ impl TypeRef { let ret_ty = inner .ret_type() .and_then(|rt| rt.type_ref()) - .map(TypeRef::from_ast) + .map(|it| TypeRef::from_ast(ctx, it)) .unwrap_or_else(|| TypeRef::Tuple(Vec::new())); let mut params = if let Some(pl) = inner.param_list() { - pl.params().map(|p| p.ascribed_type()).map(TypeRef::from_ast_opt).collect() + pl.params() + .map(|p| p.ascribed_type()) + .map(|it| TypeRef::from_ast_opt(&ctx, it)) + .collect() } else { Vec::new() }; @@ -107,19 +114,19 @@ impl TypeRef { TypeRef::Fn(params) } // for types are close enough for our purposes to the inner type for now... - ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(inner.type_ref()), + ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(&ctx, inner.type_ref()), ast::TypeRef::ImplTraitType(inner) => { - TypeRef::ImplTrait(type_bounds_from_ast(inner.type_bound_list())) + TypeRef::ImplTrait(type_bounds_from_ast(ctx, inner.type_bound_list())) } ast::TypeRef::DynTraitType(inner) => { - TypeRef::DynTrait(type_bounds_from_ast(inner.type_bound_list())) + TypeRef::DynTrait(type_bounds_from_ast(ctx, inner.type_bound_list())) } } } - pub(crate) fn from_ast_opt(node: Option) -> Self { + pub(crate) fn from_ast_opt(ctx: &LowerCtx, node: Option) -> Self { if let Some(node) = node { - TypeRef::from_ast(node) + TypeRef::from_ast(ctx, node) } else { TypeRef::Error } @@ -180,24 +187,27 @@ impl TypeRef { } } -pub(crate) fn type_bounds_from_ast(type_bounds_opt: Option) -> Vec { +pub(crate) fn type_bounds_from_ast( + lower_ctx: &LowerCtx, + type_bounds_opt: Option, +) -> Vec { if let Some(type_bounds) = type_bounds_opt { - type_bounds.bounds().map(TypeBound::from_ast).collect() + type_bounds.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect() } else { vec![] } } impl TypeBound { - pub(crate) fn from_ast(node: ast::TypeBound) -> Self { + pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::TypeBound) -> Self { match node.kind() { ast::TypeBoundKind::PathType(path_type) => { let path = match path_type.path() { Some(p) => p, None => return TypeBound::Error, }; - // FIXME: Use `Path::from_src` - let path = match Path::from_ast(path) { + + let path = match ctx.lower_path(path) { Some(p) => p, None => return TypeBound::Error, }; diff --git a/crates/ra_hir_expand/src/hygiene.rs b/crates/ra_hir_expand/src/hygiene.rs index 0b41d0e95..53866bbcb 100644 --- a/crates/ra_hir_expand/src/hygiene.rs +++ b/crates/ra_hir_expand/src/hygiene.rs @@ -12,7 +12,7 @@ use crate::{ HirFileId, HirFileIdRepr, MacroCallId, MacroDefKind, }; -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct Hygiene { // This is what `$crate` expands to def_crate: Option, -- cgit v1.2.3 From 44f5e2048ce00b0b417be95c16bae9a9ced1a5e8 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 1 May 2020 19:58:47 +0800 Subject: Remove lower_path from AssistCtx to Semantic --- crates/ra_assists/src/assist_ctx.rs | 9 +++------ .../ra_assists/src/handlers/replace_qualified_name_with_use.rs | 2 +- crates/ra_hir/src/semantics.rs | 7 ++++++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs index 3155a469b..2fe7c3de3 100644 --- a/crates/ra_assists/src/assist_ctx.rs +++ b/crates/ra_assists/src/assist_ctx.rs @@ -1,12 +1,12 @@ //! This module defines `AssistCtx` -- the API surface that is exposed to assists. use hir::Semantics; -use ra_db::{FileRange, Upcast}; +use ra_db::FileRange; use ra_fmt::{leading_indent, reindent}; use ra_ide_db::RootDatabase; use ra_syntax::{ algo::{self, find_covering_element, find_node_at_offset}, - ast, AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, - TextSize, TokenAtOffset, + AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize, + TokenAtOffset, }; use ra_text_edit::TextEditBuilder; @@ -136,9 +136,6 @@ impl<'a> AssistCtx<'a> { pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement { find_covering_element(self.source_file.syntax(), range) } - pub(crate) fn lower_path(&self, path: ast::Path) -> Option { - hir::Path::from_src(path, &hir::Hygiene::new(self.db.upcast(), self.frange.file_id.into())) - } } pub(crate) struct AssistGroup<'a> { diff --git a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs index ad59db392..918e8dd8d 100644 --- a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs +++ b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs @@ -27,7 +27,7 @@ pub(crate) fn replace_qualified_name_with_use(ctx: AssistCtx) -> Option return None; } - let hir_path = ctx.lower_path(path.clone())?; + let hir_path = ctx.sema.lower_path(&path)?; let segments = collect_hir_path_segments(&hir_path)?; if segments.len() < 2 { return None; diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index a0a0f234b..515e5eb17 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -8,7 +8,7 @@ use hir_def::{ resolver::{self, HasResolver, Resolver}, AsMacroCall, TraitId, }; -use hir_expand::ExpansionInfo; +use hir_expand::{hygiene::Hygiene, ExpansionInfo}; use hir_ty::associated_type_shorthand_candidates; use itertools::Itertools; use ra_db::{FileId, FileRange}; @@ -246,6 +246,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.analyze(path.syntax()).resolve_path(self.db, path) } + pub fn lower_path(&self, path: &ast::Path) -> Option { + let src = self.find_file(path.syntax().clone()); + Path::from_src(path.clone(), &Hygiene::new(self.db.upcast(), src.file_id.into())) + } + pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option { self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) } -- cgit v1.2.3 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 --- Cargo.lock | 68 ++++++++++++++-------- crates/ra_hir_ty/Cargo.toml | 2 +- crates/ra_proc_macro_srv/Cargo.toml | 2 +- .../tests/fixtures/test_serialize_proc_macro.txt | 7 ++- crates/ra_proc_macro_srv/src/tests/mod.rs | 6 +- crates/ra_project_model/Cargo.toml | 2 +- crates/ra_syntax/Cargo.toml | 4 +- crates/ra_syntax/src/parsing/lexer.rs | 37 +++++++----- crates/rust-analyzer/Cargo.toml | 2 +- 9 files changed, 81 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 522ecf2ee..85ea4f178 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,9 +58,9 @@ dependencies = [ [[package]] name = "backtrace-sys" -version = "0.1.36" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78848718ee1255a2485d1309ad9cdecfc2e7d0362dd11c6829364c6b35ae1bc7" +checksum = "18fbebbe1c9d1f383a9cc7e8ccdb471b91c8d024ee9c2ca5b5346121fe8b4399" dependencies = [ "cc", "libc", @@ -170,7 +170,7 @@ dependencies = [ "chalk-ir", "chalk-macros", "chalk-rust-ir", - "ena", + "ena 0.13.1", "itertools", "petgraph", "rustc-hash", @@ -199,14 +199,15 @@ dependencies = [ [[package]] name = "console" -version = "0.10.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6728a28023f207181b193262711102bfbaf47cc9d13bc71d0736607ef8efe88c" +checksum = "2586208b33573b7f76ccfbe5adb076394c88deaf81b84d7213969805b0a952a7" dependencies = [ "clicolors-control", "encode_unicode", "lazy_static", "libc", + "terminal_size", "termios", "winapi 0.3.8", ] @@ -315,6 +316,15 @@ dependencies = [ "log", ] +[[package]] +name = "ena" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3" +dependencies = [ + "log", +] + [[package]] name = "encode_unicode" version = "0.3.6" @@ -381,9 +391,9 @@ dependencies = [ [[package]] name = "fst" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eaf9ea41cc964d742f7fc7861db75d2d6e83a3ce0d897d5c6f8b621f015ddc8" +checksum = "81f9cac32c1741cdf6b66be7dcf0d9c7f25ccf12f8aa84c16cfa31f9f14513b3" [[package]] name = "fuchsia-zircon" @@ -447,9 +457,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d737e0f947a1864e93d33fdef4af8445a00d1ed8dc0c8ddb73139ea6abf15" +checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" dependencies = [ "libc", ] @@ -814,9 +824,9 @@ dependencies = [ [[package]] name = "paste" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4fb1930692d1b6a9cfabdde3d06ea0a7d186518e2f4d67660d8970e2fa647a" +checksum = "a3c897744f63f34f7ae3a024d9162bb5001f4ad661dd24bea0dc9f075d2de1c6" dependencies = [ "paste-impl", "proc-macro-hack", @@ -824,9 +834,9 @@ dependencies = [ [[package]] name = "paste-impl" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62486e111e571b1e93b710b61e8f493c0013be39629b714cb166bdb06aa5a8a" +checksum = "66fd6f92e3594f2dd7b3fc23e42d82e292f7bcda6d8e5dcd167072327234ab89" dependencies = [ "proc-macro-hack", "proc-macro2", @@ -885,9 +895,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +checksum = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7" dependencies = [ "proc-macro2", ] @@ -1023,7 +1033,7 @@ dependencies = [ "chalk-ir", "chalk-rust-ir", "chalk-solve", - "ena", + "ena 0.14.0", "insta", "itertools", "log", @@ -1374,9 +1384,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_lexer" -version = "652.0.0" +version = "656.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6a43c4d0889218c5e2ae68ffea239f303fc05ab1078c73f74e63feb87f7889" +checksum = "9cbba98ec46e96a4663197dfa8c0378752de2006e314e5400c0ca74929d6692f" dependencies = [ "unicode-xid", ] @@ -1486,18 +1496,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.104" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.104" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" +checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" dependencies = [ "proc-macro2", "quote", @@ -1506,9 +1516,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.51" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9" +checksum = "a7894c8ed05b7a3a279aeb79025fdec1d3158080b75b98a08faf2806bb799edd" dependencies = [ "itoa", "ryu", @@ -1606,6 +1616,16 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "terminal_size" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8038f95fc7a6f351163f4b964af631bd26c9e828f7db085f2a84aca56f70d13b" +dependencies = [ + "libc", + "winapi 0.3.8", +] + [[package]] name = "termios" version = "0.3.2" diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml index 04d3cd6a2..65db6d1b0 100644 --- a/crates/ra_hir_ty/Cargo.toml +++ b/crates/ra_hir_ty/Cargo.toml @@ -11,7 +11,7 @@ doctest = false itertools = "0.9.0" arrayvec = "0.5.1" smallvec = "1.2.0" -ena = "0.13.1" +ena = "0.14.0" log = "0.4.8" rustc-hash = "1.1.0" diff --git a/crates/ra_proc_macro_srv/Cargo.toml b/crates/ra_proc_macro_srv/Cargo.toml index ac2d156dc..886e14870 100644 --- a/crates/ra_proc_macro_srv/Cargo.toml +++ b/crates/ra_proc_macro_srv/Cargo.toml @@ -21,4 +21,4 @@ test_utils = { path = "../test_utils" } cargo_metadata = "0.9.1" difference = "2.0.0" # used as proc macro test target -serde_derive = "=1.0.104" +serde_derive = "=1.0.106" diff --git a/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt b/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt index 1f5d940fa..6776f5231 100644 --- a/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt +++ b/crates/ra_proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt @@ -1,5 +1,10 @@ SUBTREE $ PUNCH # [alone] 4294967295 + SUBTREE [] 4294967295 + IDENT doc 4294967295 + SUBTREE () 4294967295 + IDENT hidden 4294967295 + PUNCH # [alone] 4294967295 SUBTREE [] 4294967295 IDENT allow 4294967295 SUBTREE () 4294967295 @@ -184,4 +189,4 @@ SUBTREE $ IDENT end 4294967295 SUBTREE () 4294967295 IDENT __serde_state 4294967295 - PUNCH ; [alone] 4294967295 \ No newline at end of file + PUNCH ; [alone] 4294967295 diff --git a/crates/ra_proc_macro_srv/src/tests/mod.rs b/crates/ra_proc_macro_srv/src/tests/mod.rs index 03f79bc5d..9cf58511c 100644 --- a/crates/ra_proc_macro_srv/src/tests/mod.rs +++ b/crates/ra_proc_macro_srv/src/tests/mod.rs @@ -10,7 +10,7 @@ fn test_derive_serialize_proc_macro() { assert_expand( "serde_derive", "Serialize", - "1.0.104", + "1.0.106", r##"struct Foo {}"##, include_str!("fixtures/test_serialize_proc_macro.txt"), ); @@ -21,7 +21,7 @@ fn test_derive_serialize_proc_macro_failed() { assert_expand( "serde_derive", "Serialize", - "1.0.104", + "1.0.106", r##" struct {} "##, @@ -37,7 +37,7 @@ SUBTREE $ #[test] fn test_derive_proc_macro_list() { - let res = list("serde_derive", "1.0.104").join("\n"); + let res = list("serde_derive", "1.0.106").join("\n"); assert_eq_text!( &res, diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml index b10644b4b..5e651fe70 100644 --- a/crates/ra_project_model/Cargo.toml +++ b/crates/ra_project_model/Cargo.toml @@ -18,7 +18,7 @@ ra_db = { path = "../ra_db" } ra_cfg = { path = "../ra_cfg" } ra_proc_macro = { path = "../ra_proc_macro" } -serde = { version = "1.0.104", features = ["derive"] } +serde = { version = "1.0.106", features = ["derive"] } serde_json = "1.0.48" anyhow = "1.0.26" diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml index 7ffe46c69..c07ff488e 100644 --- a/crates/ra_syntax/Cargo.toml +++ b/crates/ra_syntax/Cargo.toml @@ -13,7 +13,7 @@ doctest = false [dependencies] itertools = "0.9.0" rowan = "0.10.0" -rustc_lexer = { version = "652.0.0", package = "rustc-ap-rustc_lexer" } +rustc_lexer = { version = "656.0.0", package = "rustc-ap-rustc_lexer" } rustc-hash = "1.1.0" arrayvec = "0.5.1" once_cell = "1.3.1" @@ -27,7 +27,7 @@ ra_parser = { path = "../ra_parser" } # ideally, `serde` should be enabled by `rust-analyzer`, but we enable it here # to reduce number of compilations smol_str = { version = "0.1.15", features = ["serde"] } -serde = { version = "1.0.104", features = ["derive"] } +serde = { version = "1.0.106", features = ["derive"] } [dev-dependencies] test_utils = { path = "../test_utils" } 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) diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 0459807fc..8c94f430a 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -26,7 +26,7 @@ pico-args = "0.3.1" rand = { version = "0.7.3", features = ["small_rng"] } relative-path = "1.0.0" rustc-hash = "1.1.0" -serde = { version = "1.0.104", features = ["derive"] } +serde = { version = "1.0.106", features = ["derive"] } serde_json = "1.0.48" threadpool = "1.7.1" -- cgit v1.2.3 From eafb2107dd176c60730f2c11a1c66d878064703c Mon Sep 17 00:00:00 2001 From: KENTARO OKUDA Date: Fri, 1 May 2020 09:43:08 -0400 Subject: Fix Typos --- docs/dev/architecture.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md index 3a337c574..cee916c09 100644 --- a/docs/dev/architecture.md +++ b/docs/dev/architecture.md @@ -46,7 +46,7 @@ can be quickly updated for small modifications. Some of the components of this repository are generated through automatic processes. `cargo xtask codegen` runs all generation tasks. Generated code is -commited to the git repository. +committed to the git repository. In particular, `cargo xtask codegen` generates: @@ -114,7 +114,7 @@ is responsible for guessing a HIR for a particular source position. Underneath, HIR works on top of salsa, using a `HirDatabase` trait. `ra_hir_xxx` crates have a strong ECS flavor, in that they work with raw ids and -directly query the databse. +directly query the database. The top-level `ra_hir` façade crate wraps ids into a more OO-flavored API. -- cgit v1.2.3 From 6833183ab45d5f0ad2e350d62c457eb8a4734b83 Mon Sep 17 00:00:00 2001 From: Diana <5275194+DianaNites@users.noreply.github.com> Date: Fri, 1 May 2020 11:49:41 -0400 Subject: Unsafe traits --- crates/ra_ide/src/display/short_label.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/ra_ide/src/display/short_label.rs b/crates/ra_ide/src/display/short_label.rs index 4b081bf6c..d37260e96 100644 --- a/crates/ra_ide/src/display/short_label.rs +++ b/crates/ra_ide/src/display/short_label.rs @@ -33,7 +33,11 @@ impl ShortLabel for ast::EnumDef { impl ShortLabel for ast::TraitDef { fn short_label(&self) -> Option { - short_label_from_node(self, "trait ") + if self.unsafe_token().is_some() { + short_label_from_node(self, "unsafe trait ") + } else { + short_label_from_node(self, "trait ") + } } } -- cgit v1.2.3 From ebff5762e9789ecd472564284994a9ac119b4166 Mon Sep 17 00:00:00 2001 From: Diana <5275194+DianaNites@users.noreply.github.com> Date: Fri, 1 May 2020 11:49:51 -0400 Subject: Test for unsafe trait --- crates/ra_ide/src/hover.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index a62f598f0..54d318858 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs @@ -869,4 +869,15 @@ fn func(foo: i32) { if true { <|>foo; }; } &[r#"pub(crate) async unsafe extern "C" fn foo()"#], ); } + + #[test] + fn test_hover_trait_show_qualifiers() { + check_hover_result( + " + //- /lib.rs + unsafe trait foo<|>() {} + ", + &["unsafe trait foo"], + ); + } } -- 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 ++++++++++++--------- .../err/0041_illegal_super_keyword_location.rast | 70 ++++++++++++ .../err/0041_illegal_super_keyword_location.rs | 4 + .../err/0042_illegal_self_keyword_location.rast | 27 +++++ .../err/0042_illegal_self_keyword_location.rs | 2 + .../parser/ok/0013_use_path_self_super.rast | 26 +---- .../parser/ok/0013_use_path_self_super.rs | 1 - xtask/src/ast_src.rs | 2 +- 9 files changed, 178 insertions(+), 75 deletions(-) create mode 100644 crates/ra_syntax/test_data/parser/err/0041_illegal_super_keyword_location.rast create mode 100644 crates/ra_syntax/test_data/parser/err/0041_illegal_super_keyword_location.rs create mode 100644 crates/ra_syntax/test_data/parser/err/0042_illegal_self_keyword_location.rast create mode 100644 crates/ra_syntax/test_data/parser/err/0042_illegal_self_keyword_location.rs 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; } } diff --git a/crates/ra_syntax/test_data/parser/err/0041_illegal_super_keyword_location.rast b/crates/ra_syntax/test_data/parser/err/0041_illegal_super_keyword_location.rast new file mode 100644 index 000000000..d0360c467 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/err/0041_illegal_super_keyword_location.rast @@ -0,0 +1,70 @@ +SOURCE_FILE@0..67 + USE_ITEM@0..12 + USE_KW@0..3 "use" + WHITESPACE@3..4 " " + USE_TREE@4..11 + PATH@4..11 + PATH_SEGMENT@4..11 + COLON2@4..6 "::" + SUPER_KW@6..11 "super" + SEMICOLON@11..12 ";" + WHITESPACE@12..13 "\n" + USE_ITEM@13..26 + USE_KW@13..16 "use" + WHITESPACE@16..17 " " + USE_TREE@17..25 + PATH@17..25 + PATH@17..18 + PATH_SEGMENT@17..18 + NAME_REF@17..18 + IDENT@17..18 "a" + COLON2@18..20 "::" + PATH_SEGMENT@20..25 + SUPER_KW@20..25 "super" + SEMICOLON@25..26 ";" + WHITESPACE@26..27 "\n" + USE_ITEM@27..47 + USE_KW@27..30 "use" + WHITESPACE@30..31 " " + USE_TREE@31..46 + PATH@31..46 + PATH@31..39 + PATH@31..36 + PATH_SEGMENT@31..36 + SUPER_KW@31..36 "super" + COLON2@36..38 "::" + PATH_SEGMENT@38..39 + NAME_REF@38..39 + IDENT@38..39 "a" + COLON2@39..41 "::" + PATH_SEGMENT@41..46 + SUPER_KW@41..46 "super" + SEMICOLON@46..47 ";" + WHITESPACE@47..48 "\n" + USE_ITEM@48..66 + USE_KW@48..51 "use" + WHITESPACE@51..52 " " + USE_TREE@52..65 + PATH@52..53 + PATH_SEGMENT@52..53 + NAME_REF@52..53 + IDENT@52..53 "a" + COLON2@53..55 "::" + USE_TREE_LIST@55..65 + L_CURLY@55..56 "{" + USE_TREE@56..64 + PATH@56..64 + PATH@56..61 + PATH_SEGMENT@56..61 + SUPER_KW@56..61 "super" + COLON2@61..63 "::" + PATH_SEGMENT@63..64 + NAME_REF@63..64 + IDENT@63..64 "b" + R_CURLY@64..65 "}" + SEMICOLON@65..66 ";" + WHITESPACE@66..67 "\n" +error 6..11: The `super` keyword may only be preceded by other `super`s +error 20..25: The `super` keyword may only be preceded by other `super`s +error 41..46: The `super` keyword may only be preceded by other `super`s +error 56..61: The `super` keyword may only be preceded by other `super`s diff --git a/crates/ra_syntax/test_data/parser/err/0041_illegal_super_keyword_location.rs b/crates/ra_syntax/test_data/parser/err/0041_illegal_super_keyword_location.rs new file mode 100644 index 000000000..bd4d58042 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/err/0041_illegal_super_keyword_location.rs @@ -0,0 +1,4 @@ +use ::super; +use a::super; +use super::a::super; +use a::{super::b}; diff --git a/crates/ra_syntax/test_data/parser/err/0042_illegal_self_keyword_location.rast b/crates/ra_syntax/test_data/parser/err/0042_illegal_self_keyword_location.rast new file mode 100644 index 000000000..4f382b06c --- /dev/null +++ b/crates/ra_syntax/test_data/parser/err/0042_illegal_self_keyword_location.rast @@ -0,0 +1,27 @@ +SOURCE_FILE@0..25 + USE_ITEM@0..11 + USE_KW@0..3 "use" + WHITESPACE@3..4 " " + USE_TREE@4..10 + PATH@4..10 + PATH_SEGMENT@4..10 + COLON2@4..6 "::" + SELF_KW@6..10 "self" + SEMICOLON@10..11 ";" + WHITESPACE@11..12 "\n" + USE_ITEM@12..24 + USE_KW@12..15 "use" + WHITESPACE@15..16 " " + USE_TREE@16..23 + PATH@16..23 + PATH@16..17 + PATH_SEGMENT@16..17 + NAME_REF@16..17 + IDENT@16..17 "a" + COLON2@17..19 "::" + PATH_SEGMENT@19..23 + SELF_KW@19..23 "self" + SEMICOLON@23..24 ";" + WHITESPACE@24..25 "\n" +error 6..10: The `self` keyword is only allowed as the first segment of a path +error 19..23: The `self` keyword is only allowed as the first segment of a path diff --git a/crates/ra_syntax/test_data/parser/err/0042_illegal_self_keyword_location.rs b/crates/ra_syntax/test_data/parser/err/0042_illegal_self_keyword_location.rs new file mode 100644 index 000000000..b9e1d7d8b --- /dev/null +++ b/crates/ra_syntax/test_data/parser/err/0042_illegal_self_keyword_location.rs @@ -0,0 +1,2 @@ +use ::self; +use a::self; diff --git a/crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rast b/crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rast index a5a90df7b..05d9c05ad 100644 --- a/crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rast +++ b/crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rast @@ -1,4 +1,4 @@ -SOURCE_FILE@0..65 +SOURCE_FILE@0..38 USE_ITEM@0..14 USE_KW@0..3 "use" WHITESPACE@3..4 " " @@ -31,27 +31,3 @@ SOURCE_FILE@0..65 IDENT@33..36 "bar" SEMICOLON@36..37 ";" WHITESPACE@37..38 "\n" - USE_ITEM@38..64 - USE_KW@38..41 "use" - WHITESPACE@41..42 " " - USE_TREE@42..63 - PATH@42..63 - PATH@42..58 - PATH@42..51 - PATH@42..48 - PATH_SEGMENT@42..48 - COLON2@42..44 "::" - SELF_KW@44..48 "self" - COLON2@48..50 "::" - PATH_SEGMENT@50..51 - NAME_REF@50..51 - IDENT@50..51 "a" - COLON2@51..53 "::" - PATH_SEGMENT@53..58 - SUPER_KW@53..58 "super" - COLON2@58..60 "::" - PATH_SEGMENT@60..63 - NAME_REF@60..63 - IDENT@60..63 "bar" - SEMICOLON@63..64 ";" - WHITESPACE@64..65 "\n" diff --git a/crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rs b/crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rs index faf6a42c7..9d9eb9917 100644 --- a/crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rs +++ b/crates/ra_syntax/test_data/parser/ok/0013_use_path_self_super.rs @@ -1,3 +1,2 @@ use self::foo; use super::super::bar; -use ::self::a::super::bar; diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs index c14804aad..1abb62f6f 100644 --- a/xtask/src/ast_src.rs +++ b/xtask/src/ast_src.rs @@ -595,7 +595,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { qualifier: Path, } struct PathSegment { - T![::], T![crate], T![<], NameRef, TypeArgList, ParamList, RetType, PathType, T![>] + T![::], T![crate], T![self], T![super], T![<], NameRef, TypeArgList, ParamList, RetType, PathType, T![>] } struct TypeArgList { T![::], -- 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(-) 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 e3ee61f5e81573a2e9415879c8740ac5d59eff06 Mon Sep 17 00:00:00 2001 From: kjeremy Date: Sun, 26 Apr 2020 18:54:05 -0400 Subject: Filter out CodeActions if a server only support commands. --- crates/rust-analyzer/src/config.rs | 6 ++++++ crates/rust-analyzer/src/main_loop/handlers.rs | 16 ++++++++++++++++ crates/rust-analyzer/tests/heavy_tests/support.rs | 6 +++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 74a63e32a..177da94cc 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -70,6 +70,7 @@ pub struct ClientCapsConfig { pub location_link: bool, pub line_folding_only: bool, pub hierarchical_symbols: bool, + pub code_action_literals: bool, } impl Default for Config { @@ -221,6 +222,11 @@ impl Config { { self.client_caps.hierarchical_symbols = value } + if let Some(value) = + caps.code_action.as_ref().and_then(|it| Some(it.code_action_literal_support.is_some())) + { + self.client_caps.code_action_literals = value; + } self.completion.allow_snippets(false); if let Some(completion) = &caps.completion { if let Some(completion_item) = &completion.completion_item { diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 8db2dfa0c..b4e539906 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -812,6 +812,22 @@ pub fn handle_code_action( } } + // If the client only supports commands then filter the list + // and remove and actions that depend on edits. + if !world.config.client_caps.code_action_literals { + res = res + .into_iter() + .filter_map(|it| match it { + cmd @ lsp_types::CodeActionOrCommand::Command(_) => Some(cmd), + lsp_types::CodeActionOrCommand::CodeAction(action) => match action.command { + Some(cmd) if action.edit.is_none() => { + Some(lsp_types::CodeActionOrCommand::Command(cmd)) + } + _ => None, + }, + }) + .collect(); + } Ok(Some(res)) } diff --git a/crates/rust-analyzer/tests/heavy_tests/support.rs b/crates/rust-analyzer/tests/heavy_tests/support.rs index e4fe3411a..8d47ee4f6 100644 --- a/crates/rust-analyzer/tests/heavy_tests/support.rs +++ b/crates/rust-analyzer/tests/heavy_tests/support.rs @@ -77,7 +77,11 @@ impl<'a> Project<'a> { let roots = self.roots.into_iter().map(|root| tmp_dir.path().join(root)).collect(); let mut config = Config { - client_caps: ClientCapsConfig { location_link: true, ..Default::default() }, + client_caps: ClientCapsConfig { + location_link: true, + code_action_literals: true, + ..Default::default() + }, with_sysroot: self.with_sysroot, ..Config::default() }; -- cgit v1.2.3 From e75565c73f935b7b4ee4182e632dfab210b26cff Mon Sep 17 00:00:00 2001 From: kjeremy Date: Sun, 26 Apr 2020 18:57:33 -0400 Subject: Advertise support for all the builtin CodeActionKinds Even thought we don't return all of these we eventually will so might as well advertise now. --- crates/rust-analyzer/src/caps.rs | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs index e22ab8402..38780726f 100644 --- a/crates/rust-analyzer/src/caps.rs +++ b/crates/rust-analyzer/src/caps.rs @@ -3,13 +3,13 @@ use crate::semantic_tokens; use lsp_types::{ - CallHierarchyServerCapability, CodeActionProviderCapability, CodeLensOptions, - CompletionOptions, DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, - ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions, - SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend, - SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, - TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability, - WorkDoneProgressOptions, + CallHierarchyServerCapability, CodeActionOptions, CodeActionProviderCapability, + CodeLensOptions, CompletionOptions, DocumentOnTypeFormattingOptions, + FoldingRangeProviderCapability, ImplementationProviderCapability, RenameOptions, + RenameProviderCapability, SaveOptions, SelectionRangeProviderCapability, + SemanticTokensDocumentProvider, SemanticTokensLegend, SemanticTokensOptions, + ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind, + TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions, }; pub fn server_capabilities() -> ServerCapabilities { @@ -40,7 +40,19 @@ pub fn server_capabilities() -> ServerCapabilities { document_highlight_provider: Some(true), document_symbol_provider: Some(true), workspace_symbol_provider: Some(true), - code_action_provider: Some(CodeActionProviderCapability::Simple(true)), + code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions { + code_action_kinds: Some(vec![ + "".to_string(), + lsp_types::code_action_kind::QUICKFIX.to_string(), + lsp_types::code_action_kind::REFACTOR.to_string(), + lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(), + lsp_types::code_action_kind::REFACTOR_INLINE.to_string(), + lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(), + lsp_types::code_action_kind::SOURCE.to_string(), + lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(), + ]), + work_done_progress_options: Default::default(), + })), code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }), document_formatting_provider: Some(true), document_range_formatting_provider: None, -- cgit v1.2.3 From ee1628dba051e691a4ced756ab3cb360543609fa Mon Sep 17 00:00:00 2001 From: kjeremy Date: Sun, 26 Apr 2020 18:58:15 -0400 Subject: Mark most assists as the base "refactor" type Most of them area. We will separate them out later but this gets them to show up in the "refactor" menu of vscode. --- crates/rust-analyzer/src/main_loop/handlers.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index b4e539906..647bdc426 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -19,8 +19,7 @@ use lsp_types::{ TextEdit, Url, WorkspaceEdit, }; use ra_ide::{ - Assist, AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, - SearchScope, + Assist, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, SearchScope, }; use ra_prof::profile; use ra_syntax::{AstNode, SyntaxKind, TextRange, TextSize}; @@ -702,15 +701,9 @@ fn create_single_code_action(assist: Assist, world: &WorldSnapshot) -> Result Some("refactor.extract.variable".to_string()), - AssistId("add_custom_impl") => Some("refactor.rewrite.add_custom_impl".to_string()), - _ => None, - }; - Ok(CodeAction { title, - kind, + kind: Some("refactor".to_owned()), diagnostics: None, edit: None, command: Some(command), -- cgit v1.2.3 From f5d20b6525bc87773dc3757cf58cb51cdd6a21a0 Mon Sep 17 00:00:00 2001 From: KENTARO OKUDA Date: Fri, 1 May 2020 14:00:06 -0400 Subject: Fix Typos on guide.md --- docs/dev/guide.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dev/guide.md b/docs/dev/guide.md index abbe4c154..c3252f1f6 100644 --- a/docs/dev/guide.md +++ b/docs/dev/guide.md @@ -26,7 +26,7 @@ properties hold: ## IDE API -To see the bigger picture of how the IDE features works, let's take a look at the [`AnalysisHost`] and +To see the bigger picture of how the IDE features work, let's take a look at the [`AnalysisHost`] and [`Analysis`] pair of types. `AnalysisHost` has three methods: * `default()` for creating an empty analysis instance @@ -131,7 +131,7 @@ mapping between `SourceRoot` IDs (which are assigned by the client) and actual analyzer. Note that `mod`, `#[path]` and `include!()` can only reference files from the -same source root. It is of course is possible to explicitly add extra files to +same source root. It is of course possible to explicitly add extra files to the source root, even `/dev/random`. ## Language Server Protocol @@ -192,7 +192,7 @@ task will be canceled as soon as the main loop calls `apply_change` on the [`schedule`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L426-L455 [The task]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop/handlers.rs#L205-L223 -This concludes the overview of the analyzer's programing *interface*. Next, lets +This concludes the overview of the analyzer's programing *interface*. Next, let's dig into the implementation! ## Salsa @@ -480,7 +480,7 @@ throughout the analyzer: ## Source Map pattern Due to an obscure edge case in completion, IDE needs to know the syntax node of -an use statement which imported the given completion candidate. We can't just +a use statement which imported the given completion candidate. We can't just store the syntax node as a part of name resolution: this will break incrementality, due to the fact that syntax changes after every file modification. -- cgit v1.2.3 From 99826dab153feffc8fe0d80600d9e812824d67b2 Mon Sep 17 00:00:00 2001 From: kjeremy Date: Fri, 1 May 2020 14:12:31 -0400 Subject: Address comments --- crates/rust-analyzer/src/caps.rs | 3 ++- crates/rust-analyzer/src/main_loop/handlers.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs index 38780726f..c0d320926 100644 --- a/crates/rust-analyzer/src/caps.rs +++ b/crates/rust-analyzer/src/caps.rs @@ -41,8 +41,9 @@ pub fn server_capabilities() -> ServerCapabilities { document_symbol_provider: Some(true), workspace_symbol_provider: Some(true), code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions { + // Advertise support for all built-in CodeActionKinds code_action_kinds: Some(vec![ - "".to_string(), + String::new(), lsp_types::code_action_kind::QUICKFIX.to_string(), lsp_types::code_action_kind::REFACTOR.to_string(), lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(), diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 647bdc426..0f623949e 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -703,7 +703,7 @@ fn create_single_code_action(assist: Assist, world: &WorldSnapshot) -> Result Date: Fri, 1 May 2020 18:26:42 -0400 Subject: Update crates --- Cargo.lock | 12 ++++++------ crates/rust-analyzer/src/caps.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85ea4f178..5d50a766f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -655,9 +655,9 @@ dependencies = [ [[package]] name = "lsp-types" -version = "0.74.0" +version = "0.74.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "820f746e5716ab9a2d664794636188bd003023b72e55404ee27105dc22869922" +checksum = "57c0e6a2b8837d27b29deb3f3e6dc1c6d2f57947677f9be1024e482ec5b59525" dependencies = [ "base64", "bitflags", @@ -706,9 +706,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.21" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" +checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" dependencies = [ "cfg-if", "fuchsia-zircon", @@ -749,9 +749,9 @@ dependencies = [ [[package]] name = "net2" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ "cfg-if", "libc", diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs index c0d320926..44222d8bd 100644 --- a/crates/rust-analyzer/src/caps.rs +++ b/crates/rust-analyzer/src/caps.rs @@ -43,7 +43,7 @@ pub fn server_capabilities() -> ServerCapabilities { code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions { // Advertise support for all built-in CodeActionKinds code_action_kinds: Some(vec![ - String::new(), + lsp_types::code_action_kind::EMPTY.to_string(), lsp_types::code_action_kind::QUICKFIX.to_string(), lsp_types::code_action_kind::REFACTOR.to_string(), lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(), -- 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_hir_def/src/body/lower.rs | 4 +++ crates/ra_hir_def/src/expr.rs | 4 +++ crates/ra_hir_ty/src/infer/expr.rs | 5 ++++ crates/ra_parser/src/grammar/expressions/atom.rs | 6 ++-- crates/ra_parser/src/syntax_kind/generated.rs | 1 + 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 ++++++++++++++++++++++-- xtask/src/ast_src.rs | 5 +++- 9 files changed, 63 insertions(+), 30 deletions(-) diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index e9dd65b0a..f06cc115b 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -203,6 +203,10 @@ impl ExprCollector<'_> { 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::LoopExpr(e) => { let body = self.collect_block_opt(e.loop_body()); diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs index aad12e123..a0cdad529 100644 --- a/crates/ra_hir_def/src/expr.rs +++ b/crates/ra_hir_def/src/expr.rs @@ -101,6 +101,9 @@ pub enum Expr { Try { expr: ExprId, }, + TryBlock { + body: ExprId, + }, Cast { expr: ExprId, type_ref: TypeRef, @@ -236,6 +239,7 @@ impl Expr { f(*expr); } } + Expr::TryBlock { body } => f(*body), Expr::Loop { body } => f(*body), Expr::While { condition, body } => { f(*condition); diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index efc60986b..83f946eee 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs @@ -73,6 +73,11 @@ impl<'a> InferenceContext<'a> { self.coerce_merge_branch(&then_ty, &else_ty) } 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 } => { self.infer_expr(*body, &Expectation::has_type(Ty::unit())); // FIXME handle break with value diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index 76aa601cb..166dfc472 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs @@ -84,7 +84,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar T![box] => box_expr(p, None), T![for] => for_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![:] => { let m = p.start(); label(p); @@ -134,7 +134,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar } }; 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::NotBlock, @@ -532,7 +532,7 @@ fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { // fn foo() { // let _ = try {}; // } -fn try_expr(p: &mut Parser, m: Option) -> CompletedMarker { +fn try_block_expr(p: &mut Parser, m: Option) -> CompletedMarker { assert!(p.at(T![try])); let m = m.unwrap_or_else(|| p.start()); // Special-case `try!` as macro. diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index ab727ed7e..524e7d784 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs @@ -191,6 +191,7 @@ pub enum SyntaxKind { RECORD_LIT, RECORD_FIELD_LIST, RECORD_FIELD, + TRY_BLOCK_EXPR, BOX_EXPR, CALL_EXPR, INDEX_EXPR, 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) diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs index 703fb9be9..1abb62f6f 100644 --- a/xtask/src/ast_src.rs +++ b/xtask/src/ast_src.rs @@ -162,6 +162,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc { "RECORD_LIT", "RECORD_FIELD_LIST", "RECORD_FIELD", + "TRY_BLOCK_EXPR", "BOX_EXPR", // postfix "CALL_EXPR", @@ -439,6 +440,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { } struct IfExpr: AttrsOwner { T![if], Condition } struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] } + struct TryBlockExpr: AttrsOwner { T![try], body: BlockExpr } struct ForExpr: AttrsOwner, LoopBodyOwner { T![for], Pat, @@ -449,7 +451,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] } struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr } struct Label { T![lifetime] } - struct BlockExpr: AttrsOwner { Label, T![unsafe], T![async], Block } + struct BlockExpr: AttrsOwner { Label, T![unsafe], T![async], Block } struct ReturnExpr: AttrsOwner { Expr } struct CallExpr: ArgListOwner { Expr } struct MethodCallExpr: AttrsOwner, ArgListOwner { @@ -720,6 +722,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { FieldExpr, AwaitExpr, TryExpr, + TryBlockExpr, CastExpr, RefExpr, PrefixExpr, -- cgit v1.2.3 From 76f34a15e61fc69ccafe1ec4804712dcd3069de5 Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Fri, 1 May 2020 19:13:52 -0400 Subject: Improve formatting of analyzer status text --- crates/rust-analyzer/src/main_loop/handlers.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 0f623949e..574e070fc 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -46,11 +46,11 @@ use crate::{ pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result { let _p = profile("handle_analyzer_status"); let mut buf = world.status(); - format_to!(buf, "\n\nrequests:"); + format_to!(buf, "\n\nrequests:\n"); let requests = world.latest_requests.read(); for (is_last, r) in requests.iter() { let mark = if is_last { "*" } else { " " }; - format_to!(buf, "{}{:4} {:<36}{}ms", mark, r.id, r.method, r.duration.as_millis()); + format_to!(buf, "{}{:4} {:<36}{}ms\n", mark, r.id, r.method, r.duration.as_millis()); } Ok(buf) } -- cgit v1.2.3 From 247d32cbfdc2683ee4f6fd1474b65840131551dc Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 2 May 2020 10:57:37 +0200 Subject: Test/check the whole package Closes #4255 --- crates/rust-analyzer/src/main_loop/handlers.rs | 6 +----- crates/rust-analyzer/tests/heavy_tests/main.rs | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 0f623949e..914062902 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -400,11 +400,7 @@ pub fn handle_runnables( range: Default::default(), label: format!("cargo {} -p {}", cmd, spec.package), bin: "cargo".to_string(), - args: { - let mut args = vec![cmd.to_string()]; - spec.clone().push_to(&mut args); - args - }, + args: vec![cmd.to_string(), "--package".to_string(), spec.package.clone()], extra_args: Vec::new(), env: FxHashMap::default(), cwd: workspace_root.map(|root| root.to_owned()), diff --git a/crates/rust-analyzer/tests/heavy_tests/main.rs b/crates/rust-analyzer/tests/heavy_tests/main.rs index 07b8114c6..a218da76d 100644 --- a/crates/rust-analyzer/tests/heavy_tests/main.rs +++ b/crates/rust-analyzer/tests/heavy_tests/main.rs @@ -149,7 +149,7 @@ fn main() {} "cwd": server.path().join("foo") }, { - "args": [ "check", "--package", "foo", "--test", "spam" ], + "args": [ "check", "--package", "foo" ], "extraArgs": [], "bin": "cargo", "env": {}, @@ -161,7 +161,7 @@ fn main() {} "cwd": server.path().join("foo") }, { - "args": [ "test", "--package", "foo", "--test", "spam" ], + "args": [ "test", "--package", "foo" ], "extraArgs": [], "bin": "cargo", "env": {}, -- 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_assists/src/handlers/early_return.rs | 16 +-- .../src/handlers/inline_local_variable.rs | 1 + .../ra_assists/src/handlers/introduce_variable.rs | 2 +- crates/ra_assists/src/handlers/move_guard.rs | 4 +- crates/ra_fmt/src/lib.rs | 1 - crates/ra_hir_def/src/body/lower.rs | 24 ++-- crates/ra_hir_expand/src/db.rs | 3 +- crates/ra_ide/src/completion/completion_context.rs | 2 +- crates/ra_ide/src/folding_ranges.rs | 2 +- crates/ra_ide/src/join_lines.rs | 3 +- crates/ra_ide/src/syntax_tree.rs | 77 +++++------ crates/ra_mbe/src/tests.rs | 152 ++++++++++----------- crates/ra_parser/src/grammar.rs | 2 +- crates/ra_parser/src/grammar/expressions.rs | 13 +- crates/ra_parser/src/grammar/expressions/atom.rs | 29 ++-- crates/ra_parser/src/syntax_kind/generated.rs | 3 +- 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 ++- xtask/src/ast_src.rs | 19 +-- xtask/src/codegen/gen_syntax.rs | 1 + 25 files changed, 242 insertions(+), 261 deletions(-) diff --git a/crates/ra_assists/src/handlers/early_return.rs b/crates/ra_assists/src/handlers/early_return.rs index ea6c56f8c..eede2fe91 100644 --- a/crates/ra_assists/src/handlers/early_return.rs +++ b/crates/ra_assists/src/handlers/early_return.rs @@ -2,7 +2,7 @@ use std::{iter::once, ops::RangeInclusive}; use ra_syntax::{ algo::replace_children, - ast::{self, edit::IndentLevel, make, Block, Pat::TupleStructPat}, + ast::{self, edit::IndentLevel, make}, AstNode, SyntaxKind::{FN_DEF, LOOP_EXPR, L_CURLY, R_CURLY, WHILE_EXPR, WHITESPACE}, SyntaxNode, @@ -47,7 +47,7 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option { // Check if there is an IfLet that we can handle. let if_let_pat = match cond.pat() { None => None, // No IfLet, supported. - Some(TupleStructPat(pat)) if pat.args().count() == 1 => { + Some(ast::Pat::TupleStructPat(pat)) if pat.args().count() == 1 => { let path = pat.path()?; match path.qualifier() { None => { @@ -61,9 +61,9 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option { }; let cond_expr = cond.expr()?; - let then_block = if_expr.then_branch()?.block()?; + let then_block = if_expr.then_branch()?; - let parent_block = if_expr.syntax().parent()?.ancestors().find_map(ast::Block::cast)?; + let parent_block = if_expr.syntax().parent()?.ancestors().find_map(ast::BlockExpr::cast)?; if parent_block.expr()? != if_expr.clone().into() { return None; @@ -80,7 +80,7 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option { return None; } - let parent_container = parent_block.syntax().parent()?.parent()?; + let parent_container = parent_block.syntax().parent()?; let early_expression: ast::Expr = match parent_container.kind() { WHILE_EXPR | LOOP_EXPR => make::expr_continue(), @@ -144,13 +144,13 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option { } }; edit.target(if_expr.syntax().text_range()); - edit.replace_ast(parent_block, ast::Block::cast(new_block).unwrap()); + edit.replace_ast(parent_block, ast::BlockExpr::cast(new_block).unwrap()); edit.set_cursor(cursor_position); fn replace( new_expr: &SyntaxNode, - then_block: &Block, - parent_block: &Block, + then_block: &ast::BlockExpr, + parent_block: &ast::BlockExpr, if_expr: &ast::IfExpr, ) -> SyntaxNode { let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone()); diff --git a/crates/ra_assists/src/handlers/inline_local_variable.rs b/crates/ra_assists/src/handlers/inline_local_variable.rs index f5702f6e0..60ec536a7 100644 --- a/crates/ra_assists/src/handlers/inline_local_variable.rs +++ b/crates/ra_assists/src/handlers/inline_local_variable.rs @@ -89,6 +89,7 @@ pub(crate) fn inline_local_variable(ctx: AssistCtx) -> Option { | (ast::Expr::ParenExpr(_), _) | (ast::Expr::PathExpr(_), _) | (ast::Expr::BlockExpr(_), _) + | (ast::Expr::EffectExpr(_), _) | (_, ast::Expr::CallExpr(_)) | (_, ast::Expr::TupleExpr(_)) | (_, ast::Expr::ArrayExpr(_)) diff --git a/crates/ra_assists/src/handlers/introduce_variable.rs b/crates/ra_assists/src/handlers/introduce_variable.rs index eda9ac296..39c656305 100644 --- a/crates/ra_assists/src/handlers/introduce_variable.rs +++ b/crates/ra_assists/src/handlers/introduce_variable.rs @@ -111,7 +111,7 @@ fn valid_target_expr(node: SyntaxNode) -> Option { /// expression like a lambda or match arm. fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> { expr.syntax().ancestors().find_map(|node| { - if let Some(expr) = node.parent().and_then(ast::Block::cast).and_then(|it| it.expr()) { + if let Some(expr) = node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) { if expr.syntax() == &node { tested_by!(test_introduce_var_last_expr); return Some((node, false)); diff --git a/crates/ra_assists/src/handlers/move_guard.rs b/crates/ra_assists/src/handlers/move_guard.rs index d5ccdd91c..b084dd9ee 100644 --- a/crates/ra_assists/src/handlers/move_guard.rs +++ b/crates/ra_assists/src/handlers/move_guard.rs @@ -113,9 +113,9 @@ pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option { "Move condition to match guard", |edit| { edit.target(if_expr.syntax().text_range()); - let then_only_expr = then_block.block().and_then(|it| it.statements().next()).is_none(); + let then_only_expr = then_block.statements().next().is_none(); - match &then_block.block().and_then(|it| it.expr()) { + match &then_block.expr() { Some(then_expr) if then_only_expr => { edit.replace(if_expr.syntax().text_range(), then_expr.syntax().text()) } diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs index 1a30b2b3a..f910ded9d 100644 --- a/crates/ra_fmt/src/lib.rs +++ b/crates/ra_fmt/src/lib.rs @@ -42,7 +42,6 @@ pub fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { } pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option { - let block = block.block()?; let has_anything_else = |thing: &SyntaxNode| -> bool { let mut non_trivial_children = block.syntax().children_with_tokens().filter(|it| match it.kind() { diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index f06cc115b..58b3d10d8 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -203,10 +203,16 @@ impl ExprCollector<'_> { 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::EffectExpr(e) => match e.effect() { + ast::Effect::Try(_) => { + let body = self.collect_block_opt(e.block_expr()); + self.alloc_expr(Expr::TryBlock { body }, syntax_ptr) + } + // FIXME: we need to record these effects somewhere... + ast::Effect::Async(_) | ast::Effect::Label(_) | ast::Effect::Unsafe(_) => { + self.collect_block_opt(e.block_expr()) + } + }, ast::Expr::BlockExpr(e) => self.collect_block(e), ast::Expr::LoopExpr(e) => { let body = self.collect_block_opt(e.loop_body()); @@ -494,12 +500,8 @@ impl ExprCollector<'_> { } } - fn collect_block(&mut self, expr: ast::BlockExpr) -> ExprId { - let syntax_node_ptr = AstPtr::new(&expr.clone().into()); - let block = match expr.block() { - Some(block) => block, - None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), - }; + fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId { + let syntax_node_ptr = AstPtr::new(&block.clone().into()); self.collect_block_items(&block); let statements = block .statements() @@ -517,7 +519,7 @@ impl ExprCollector<'_> { self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) } - fn collect_block_items(&mut self, block: &ast::Block) { + fn collect_block_items(&mut self, block: &ast::BlockExpr) { let container = ContainerId::DefWithBodyId(self.def); for item in block.items() { let (def, name): (ModuleDefId, Option) = match item { diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs index 047452306..4c12d0a15 100644 --- a/crates/ra_hir_expand/src/db.rs +++ b/crates/ra_hir_expand/src/db.rs @@ -330,7 +330,7 @@ fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind { FragmentKind::Expr } // FIXME: Expand to statements in appropriate positions; HIR lowering needs to handle that - EXPR_STMT | BLOCK => FragmentKind::Expr, + EXPR_STMT | BLOCK_EXPR => FragmentKind::Expr, ARG_LIST => FragmentKind::Expr, TRY_EXPR => FragmentKind::Expr, TUPLE_EXPR => FragmentKind::Expr, @@ -342,7 +342,6 @@ fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind { CONDITION => FragmentKind::Expr, BREAK_EXPR => FragmentKind::Expr, RETURN_EXPR => FragmentKind::Expr, - BLOCK_EXPR => FragmentKind::Expr, MATCH_EXPR => FragmentKind::Expr, MATCH_ARM => FragmentKind::Expr, MATCH_GUARD => FragmentKind::Expr, diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index 118fceb2e..c529752d4 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs @@ -344,7 +344,7 @@ impl<'a> CompletionContext<'a> { stmt.syntax().text_range() == name_ref.syntax().text_range(), ); } - if let Some(block) = ast::Block::cast(node) { + if let Some(block) = ast::BlockExpr::cast(node) { return Some( block.expr().map(|e| e.syntax().text_range()) == Some(name_ref.syntax().text_range()), diff --git a/crates/ra_ide/src/folding_ranges.rs b/crates/ra_ide/src/folding_ranges.rs index 4379005aa..8657377de 100644 --- a/crates/ra_ide/src/folding_ranges.rs +++ b/crates/ra_ide/src/folding_ranges.rs @@ -88,7 +88,7 @@ fn fold_kind(kind: SyntaxKind) -> Option { | ITEM_LIST | EXTERN_ITEM_LIST | USE_TREE_LIST - | BLOCK + | BLOCK_EXPR | MATCH_ARM_LIST | ENUM_VARIANT_LIST | TOKEN_TREE => Some(FoldKind::Block), diff --git a/crates/ra_ide/src/join_lines.rs b/crates/ra_ide/src/join_lines.rs index d0def7eaa..63fd6b3e4 100644 --- a/crates/ra_ide/src/join_lines.rs +++ b/crates/ra_ide/src/join_lines.rs @@ -129,8 +129,7 @@ fn has_comma_after(node: &SyntaxNode) -> bool { } fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> { - let block = ast::Block::cast(token.parent())?; - let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; + let block_expr = ast::BlockExpr::cast(token.parent())?; if !block_expr.is_standalone() { return None; } diff --git a/crates/ra_ide/src/syntax_tree.rs b/crates/ra_ide/src/syntax_tree.rs index bf97f8c56..86c70ff83 100644 --- a/crates/ra_ide/src/syntax_tree.rs +++ b/crates/ra_ide/src/syntax_tree.rs @@ -120,9 +120,8 @@ SOURCE_FILE@0..11 R_PAREN@7..8 ")" WHITESPACE@8..9 " " BLOCK_EXPR@9..11 - BLOCK@9..11 - L_CURLY@9..10 "{" - R_CURLY@10..11 "}" + L_CURLY@9..10 "{" + R_CURLY@10..11 "}" "# .trim() ); @@ -153,26 +152,25 @@ SOURCE_FILE@0..60 R_PAREN@8..9 ")" WHITESPACE@9..10 " " BLOCK_EXPR@10..60 - BLOCK@10..60 - L_CURLY@10..11 "{" - WHITESPACE@11..16 "\n " - EXPR_STMT@16..58 - MACRO_CALL@16..57 - PATH@16..22 - PATH_SEGMENT@16..22 - NAME_REF@16..22 - IDENT@16..22 "assert" - BANG@22..23 "!" - TOKEN_TREE@23..57 - L_PAREN@23..24 "(" - STRING@24..52 "\"\n fn foo() {\n ..." - COMMA@52..53 "," - WHITESPACE@53..54 " " - STRING@54..56 "\"\"" - R_PAREN@56..57 ")" - SEMICOLON@57..58 ";" - WHITESPACE@58..59 "\n" - R_CURLY@59..60 "}" + L_CURLY@10..11 "{" + WHITESPACE@11..16 "\n " + EXPR_STMT@16..58 + MACRO_CALL@16..57 + PATH@16..22 + PATH_SEGMENT@16..22 + NAME_REF@16..22 + IDENT@16..22 "assert" + BANG@22..23 "!" + TOKEN_TREE@23..57 + L_PAREN@23..24 "(" + STRING@24..52 "\"\n fn foo() {\n ..." + COMMA@52..53 "," + WHITESPACE@53..54 " " + STRING@54..56 "\"\"" + R_PAREN@56..57 ")" + SEMICOLON@57..58 ";" + WHITESPACE@58..59 "\n" + R_CURLY@59..60 "}" "# .trim() ); @@ -196,9 +194,8 @@ FN_DEF@0..11 R_PAREN@7..8 ")" WHITESPACE@8..9 " " BLOCK_EXPR@9..11 - BLOCK@9..11 - L_CURLY@9..10 "{" - R_CURLY@10..11 "}" + L_CURLY@9..10 "{" + R_CURLY@10..11 "}" "# .trim() ); @@ -265,10 +262,9 @@ SOURCE_FILE@0..12 R_PAREN@7..8 ")" WHITESPACE@8..9 " " BLOCK_EXPR@9..12 - BLOCK@9..12 - L_CURLY@9..10 "{" - WHITESPACE@10..11 "\n" - R_CURLY@11..12 "}" + L_CURLY@9..10 "{" + WHITESPACE@10..11 "\n" + R_CURLY@11..12 "}" "# .trim() ); @@ -300,10 +296,9 @@ SOURCE_FILE@0..12 R_PAREN@7..8 ")" WHITESPACE@8..9 " " BLOCK_EXPR@9..12 - BLOCK@9..12 - L_CURLY@9..10 "{" - WHITESPACE@10..11 "\n" - R_CURLY@11..12 "}" + L_CURLY@9..10 "{" + WHITESPACE@10..11 "\n" + R_CURLY@11..12 "}" "# .trim() ); @@ -334,10 +329,9 @@ SOURCE_FILE@0..25 R_PAREN@7..8 ")" WHITESPACE@8..9 " " BLOCK_EXPR@9..12 - BLOCK@9..12 - L_CURLY@9..10 "{" - WHITESPACE@10..11 "\n" - R_CURLY@11..12 "}" + L_CURLY@9..10 "{" + WHITESPACE@10..11 "\n" + R_CURLY@11..12 "}" WHITESPACE@12..13 "\n" FN_DEF@13..25 FN_KW@13..15 "fn" @@ -349,10 +343,9 @@ SOURCE_FILE@0..25 R_PAREN@20..21 ")" WHITESPACE@21..22 " " BLOCK_EXPR@22..25 - BLOCK@22..25 - L_CURLY@22..23 "{" - WHITESPACE@23..24 "\n" - R_CURLY@24..25 "}" + L_CURLY@22..23 "{" + WHITESPACE@23..24 "\n" + R_CURLY@24..25 "}" "# .trim() ); diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs index 0d924ce58..c43003fd6 100644 --- a/crates/ra_mbe/src/tests.rs +++ b/crates/ra_mbe/src/tests.rs @@ -266,21 +266,20 @@ fn test_expr_order() { L_PAREN@5..6 "(" R_PAREN@6..7 ")" BLOCK_EXPR@7..15 - BLOCK@7..15 - L_CURLY@7..8 "{" - EXPR_STMT@8..14 - BIN_EXPR@8..13 - BIN_EXPR@8..11 - LITERAL@8..9 - INT_NUMBER@8..9 "1" - PLUS@9..10 "+" - LITERAL@10..11 - INT_NUMBER@10..11 "1" - STAR@11..12 "*" - LITERAL@12..13 - INT_NUMBER@12..13 "2" - SEMICOLON@13..14 ";" - R_CURLY@14..15 "}""#, + L_CURLY@7..8 "{" + EXPR_STMT@8..14 + BIN_EXPR@8..13 + BIN_EXPR@8..11 + LITERAL@8..9 + INT_NUMBER@8..9 "1" + PLUS@9..10 "+" + LITERAL@10..11 + INT_NUMBER@10..11 "1" + STAR@11..12 "*" + LITERAL@12..13 + INT_NUMBER@12..13 "2" + SEMICOLON@13..14 ";" + R_CURLY@14..15 "}""#, ); } @@ -1114,68 +1113,67 @@ fn test_vec() { assert_eq!( format!("{:#?}", tree).trim(), r#"BLOCK_EXPR@0..45 - BLOCK@0..45 - L_CURLY@0..1 "{" - LET_STMT@1..20 - LET_KW@1..4 "let" - BIND_PAT@4..8 - MUT_KW@4..7 "mut" - NAME@7..8 - IDENT@7..8 "v" - EQ@8..9 "=" - CALL_EXPR@9..19 - PATH_EXPR@9..17 - PATH@9..17 - PATH@9..12 - PATH_SEGMENT@9..12 - NAME_REF@9..12 - IDENT@9..12 "Vec" - COLON2@12..14 "::" - PATH_SEGMENT@14..17 - NAME_REF@14..17 - IDENT@14..17 "new" - ARG_LIST@17..19 - L_PAREN@17..18 "(" - R_PAREN@18..19 ")" - SEMICOLON@19..20 ";" - EXPR_STMT@20..33 - METHOD_CALL_EXPR@20..32 - PATH_EXPR@20..21 - PATH@20..21 - PATH_SEGMENT@20..21 - NAME_REF@20..21 - IDENT@20..21 "v" - DOT@21..22 "." - NAME_REF@22..26 - IDENT@22..26 "push" - ARG_LIST@26..32 - L_PAREN@26..27 "(" - LITERAL@27..31 - INT_NUMBER@27..31 "1u32" - R_PAREN@31..32 ")" - SEMICOLON@32..33 ";" - EXPR_STMT@33..43 - METHOD_CALL_EXPR@33..42 - PATH_EXPR@33..34 - PATH@33..34 - PATH_SEGMENT@33..34 - NAME_REF@33..34 - IDENT@33..34 "v" - DOT@34..35 "." - NAME_REF@35..39 - IDENT@35..39 "push" - ARG_LIST@39..42 - L_PAREN@39..40 "(" - LITERAL@40..41 - INT_NUMBER@40..41 "2" - R_PAREN@41..42 ")" - SEMICOLON@42..43 ";" - PATH_EXPR@43..44 - PATH@43..44 - PATH_SEGMENT@43..44 - NAME_REF@43..44 - IDENT@43..44 "v" - R_CURLY@44..45 "}""# + L_CURLY@0..1 "{" + LET_STMT@1..20 + LET_KW@1..4 "let" + BIND_PAT@4..8 + MUT_KW@4..7 "mut" + NAME@7..8 + IDENT@7..8 "v" + EQ@8..9 "=" + CALL_EXPR@9..19 + PATH_EXPR@9..17 + PATH@9..17 + PATH@9..12 + PATH_SEGMENT@9..12 + NAME_REF@9..12 + IDENT@9..12 "Vec" + COLON2@12..14 "::" + PATH_SEGMENT@14..17 + NAME_REF@14..17 + IDENT@14..17 "new" + ARG_LIST@17..19 + L_PAREN@17..18 "(" + R_PAREN@18..19 ")" + SEMICOLON@19..20 ";" + EXPR_STMT@20..33 + METHOD_CALL_EXPR@20..32 + PATH_EXPR@20..21 + PATH@20..21 + PATH_SEGMENT@20..21 + NAME_REF@20..21 + IDENT@20..21 "v" + DOT@21..22 "." + NAME_REF@22..26 + IDENT@22..26 "push" + ARG_LIST@26..32 + L_PAREN@26..27 "(" + LITERAL@27..31 + INT_NUMBER@27..31 "1u32" + R_PAREN@31..32 ")" + SEMICOLON@32..33 ";" + EXPR_STMT@33..43 + METHOD_CALL_EXPR@33..42 + PATH_EXPR@33..34 + PATH@33..34 + PATH_SEGMENT@33..34 + NAME_REF@33..34 + IDENT@33..34 "v" + DOT@34..35 "." + NAME_REF@35..39 + IDENT@35..39 "push" + ARG_LIST@39..42 + L_PAREN@39..40 "(" + LITERAL@40..41 + INT_NUMBER@40..41 "2" + R_PAREN@41..42 ")" + SEMICOLON@42..43 ";" + PATH_EXPR@43..44 + PATH@43..44 + PATH_SEGMENT@43..44 + NAME_REF@43..44 + IDENT@43..44 "v" + R_CURLY@44..45 "}""# ); } diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs index c2a6e82e9..d9824ff9b 100644 --- a/crates/ra_parser/src/grammar.rs +++ b/crates/ra_parser/src/grammar.rs @@ -143,7 +143,7 @@ pub(crate) fn reparser( parent: Option, ) -> Option { let res = match node { - BLOCK => expressions::naked_block, + BLOCK_EXPR => expressions::block, RECORD_FIELD_DEF_LIST => items::record_field_def_list, RECORD_FIELD_LIST => items::record_field_list, ENUM_VARIANT_LIST => items::enum_variant_list, diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index cb30b25a8..a23dbcacf 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs @@ -59,16 +59,7 @@ pub(crate) fn block(p: &mut Parser) { p.error("expected a block"); return; } - atom::block_expr(p, None); -} - -pub(crate) fn naked_block(p: &mut Parser) { - assert!(p.at(T!['{'])); - let m = p.start(); - p.bump(T!['{']); - expr_block_contents(p); - p.expect(T!['}']); - m.complete(p, BLOCK); + atom::block_expr(p); } fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool { @@ -197,7 +188,7 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) { } } -pub(crate) fn expr_block_contents(p: &mut Parser) { +pub(super) fn expr_block_contents(p: &mut Parser) { // This is checked by a validator attributes::inner_attributes(p); diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index 166dfc472..c76b7330c 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs @@ -92,7 +92,10 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar T![loop] => loop_expr(p, Some(m)), T![for] => for_expr(p, Some(m)), T![while] => while_expr(p, Some(m)), - T!['{'] => block_expr(p, Some(m)), + T!['{'] => { + block_expr(p); + m.complete(p, EFFECT_EXPR) + } _ => { // test_err misplaced_label_err // fn main() { @@ -108,13 +111,15 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar let m = p.start(); p.bump(T![async]); p.eat(T![move]); - block_expr(p, Some(m)) + block_expr(p); + m.complete(p, EFFECT_EXPR) } T![match] => match_expr(p), T![unsafe] if la == T!['{'] => { let m = p.start(); p.bump(T![unsafe]); - block_expr(p, Some(m)) + block_expr(p); + m.complete(p, EFFECT_EXPR) } T!['{'] => { // test for_range_from @@ -123,7 +128,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar // break; // } // } - block_expr(p, None) + block_expr(p) } T![return] => return_expr(p), T![continue] => continue_expr(p), @@ -134,7 +139,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar } }; let blocklike = match done.kind() { - IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | TRY_BLOCK_EXPR => { + IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | EFFECT_EXPR => { BlockLike::Block } _ => BlockLike::NotBlock, @@ -234,7 +239,7 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker { if p.at(T!['{']) { // test lambda_ret_block // fn main() { || -> i32 { 92 }(); } - block_expr(p, None); + block_expr(p); } else { p.error("expected `{`"); } @@ -464,10 +469,12 @@ fn match_guard(p: &mut Parser) -> CompletedMarker { // unsafe {}; // 'label: {}; // } -pub(super) fn block_expr(p: &mut Parser, m: Option) -> CompletedMarker { +pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker { assert!(p.at(T!['{'])); - let m = m.unwrap_or_else(|| p.start()); - naked_block(p); + let m = p.start(); + p.bump(T!['{']); + expr_block_contents(p); + p.expect(T!['}']); m.complete(p, BLOCK_EXPR) } @@ -552,8 +559,8 @@ fn try_block_expr(p: &mut Parser, m: Option) -> CompletedMarker { } p.bump(T![try]); - block(p); - m.complete(p, TRY_EXPR) + block_expr(p); + m.complete(p, EFFECT_EXPR) } // test box_expr diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index 524e7d784..e7404492a 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs @@ -191,7 +191,7 @@ pub enum SyntaxKind { RECORD_LIT, RECORD_FIELD_LIST, RECORD_FIELD, - TRY_BLOCK_EXPR, + EFFECT_EXPR, BOX_EXPR, CALL_EXPR, INDEX_EXPR, @@ -204,7 +204,6 @@ pub enum SyntaxKind { PREFIX_EXPR, RANGE_EXPR, BIN_EXPR, - BLOCK, EXTERN_BLOCK, EXTERN_ITEM_LIST, ENUM_VARIANT, 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