From 128eef779f572a8120cb475d86a373ac4c9e5559 Mon Sep 17 00:00:00 2001 From: unexge Date: Thu, 13 Aug 2020 00:51:15 +0300 Subject: Improve AST replacing in expand glob import --- crates/assists/src/handlers/expand_glob_import.rs | 267 +++++++++++++++++++--- 1 file changed, 229 insertions(+), 38 deletions(-) diff --git a/crates/assists/src/handlers/expand_glob_import.rs b/crates/assists/src/handlers/expand_glob_import.rs index 81d0af2f3..0288d1c77 100644 --- a/crates/assists/src/handlers/expand_glob_import.rs +++ b/crates/assists/src/handlers/expand_glob_import.rs @@ -4,7 +4,7 @@ use ide_db::{ defs::{classify_name_ref, Definition, NameRefClass}, RootDatabase, }; -use syntax::{algo, ast, match_ast, AstNode, SyntaxNode, SyntaxToken, T}; +use syntax::{ast, AstNode, SyntaxToken, T}; use crate::{ assist_context::{AssistBuilder, AssistContext, Assists}, @@ -38,7 +38,7 @@ use crate::{ // ``` pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { let star = ctx.find_token_at_offset(T![*])?; - let mod_path = find_mod_path(&star)?; + let (parent, mod_path) = find_parent_and_path(&star)?; let module = match ctx.sema.resolve_path(&mod_path)? { PathResolution::Def(ModuleDef::Module(it)) => it, _ => return None, @@ -52,19 +52,23 @@ pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Opti source_file.syntax().descendants().filter_map(ast::NameRef::cast).collect(); let used_names = find_used_names(ctx, defs_in_mod, name_refs_in_source_file); - let parent = star.parent().parent()?; + let target = parent.syntax(); acc.add( AssistId("expand_glob_import", AssistKind::RefactorRewrite), "Expand glob import", - parent.text_range(), + target.text_range(), |builder| { - replace_ast(builder, &parent, mod_path, used_names); + replace_ast(builder, parent, mod_path, used_names); }, ) } -fn find_mod_path(star: &SyntaxToken) -> Option { - star.ancestors().find_map(|n| ast::UseTree::cast(n).and_then(|u| u.path())) +fn find_parent_and_path(star: &SyntaxToken) -> Option<(ast::UseTree, ast::Path)> { + star.ancestors().find_map(|n| { + let use_tree = ast::UseTree::cast(n)?; + let path = use_tree.path()?; + Some((use_tree, path)) + }) } #[derive(PartialEq)] @@ -137,41 +141,28 @@ fn find_used_names( fn replace_ast( builder: &mut AssistBuilder, - node: &SyntaxNode, + parent: ast::UseTree, path: ast::Path, used_names: Vec, ) { - let replacement: Either = match used_names.as_slice() { - [name] => Either::Left(ast::make::use_tree( + let replacement = match used_names.as_slice() { + [name] => ast::make::use_tree( ast::make::path_from_text(&format!("{}::{}", path, name)), None, None, false, - )), - names => Either::Right(ast::make::use_tree_list(names.iter().map(|n| { - ast::make::use_tree(ast::make::path_from_text(&n.to_string()), None, None, false) - }))), - }; - - let mut replace_node = |replacement: Either| { - algo::diff(node, &replacement.either(|u| u.syntax().clone(), |ut| ut.syntax().clone())) - .into_text_edit(builder.text_edit_builder()); + ), + names => ast::make::use_tree( + path, + Some(ast::make::use_tree_list(names.iter().map(|n| { + ast::make::use_tree(ast::make::path_from_text(&n.to_string()), None, None, false) + }))), + None, + false, + ), }; - match_ast! { - match node { - ast::UseTree(use_tree) => { - replace_node(replacement); - }, - ast::UseTreeList(use_tree_list) => { - replace_node(replacement); - }, - ast::Use(use_item) => { - builder.replace_ast(use_item, ast::make::use_(replacement.left_or_else(|ut| ast::make::use_tree(path, Some(ut), None, false)))); - }, - _ => {}, - } - } + builder.replace_ast(parent, replacement); } #[cfg(test)] @@ -260,7 +251,7 @@ fn qux(bar: Bar, baz: Baz) { expand_glob_import, r" mod foo { - mod bar { + pub mod bar { pub struct Bar; pub struct Baz; pub struct Qux; @@ -268,7 +259,7 @@ mod foo { pub fn f() {} } - mod baz { + pub mod baz { pub fn g() {} } } @@ -282,7 +273,7 @@ fn qux(bar: Bar, baz: Baz) { ", r" mod foo { - mod bar { + pub mod bar { pub struct Bar; pub struct Baz; pub struct Qux; @@ -290,7 +281,7 @@ mod foo { pub fn f() {} } - mod baz { + pub mod baz { pub fn g() {} } } @@ -302,7 +293,207 @@ fn qux(bar: Bar, baz: Baz) { g(); } ", - ) + ); + + check_assist( + expand_glob_import, + r" +mod foo { + pub mod bar { + pub struct Bar; + pub struct Baz; + pub struct Qux; + + pub fn f() {} + } + + pub mod baz { + pub fn g() {} + } +} + +use foo::{bar::{Bar, Baz, f}, baz::*<|>}; + +fn qux(bar: Bar, baz: Baz) { + f(); + g(); +} +", + r" +mod foo { + pub mod bar { + pub struct Bar; + pub struct Baz; + pub struct Qux; + + pub fn f() {} + } + + pub mod baz { + pub fn g() {} + } +} + +use foo::{bar::{Bar, Baz, f}, baz::g}; + +fn qux(bar: Bar, baz: Baz) { + f(); + g(); +} +", + ); + + check_assist( + expand_glob_import, + r" +mod foo { + pub mod bar { + pub struct Bar; + pub struct Baz; + pub struct Qux; + + pub fn f() {} + } + + pub mod baz { + pub fn g() {} + + pub mod qux { + pub fn h() {} + pub fn m() {} + + pub mod q { + pub fn j() {} + } + } + } +} + +use foo::{ + bar::{*, f}, + baz::{g, qux::*<|>} +}; + +fn qux(bar: Bar, baz: Baz) { + f(); + g(); + h(); + q::j(); +} +", + r" +mod foo { + pub mod bar { + pub struct Bar; + pub struct Baz; + pub struct Qux; + + pub fn f() {} + } + + pub mod baz { + pub fn g() {} + + pub mod qux { + pub fn h() {} + pub fn m() {} + + pub mod q { + pub fn j() {} + } + } + } +} + +use foo::{ + bar::{*, f}, + baz::{g, qux::{q, h}} +}; + +fn qux(bar: Bar, baz: Baz) { + f(); + g(); + h(); + q::j(); +} +", + ); + + check_assist( + expand_glob_import, + r" +mod foo { + pub mod bar { + pub struct Bar; + pub struct Baz; + pub struct Qux; + + pub fn f() {} + } + + pub mod baz { + pub fn g() {} + + pub mod qux { + pub fn h() {} + pub fn m() {} + + pub mod q { + pub fn j() {} + } + } + } +} + +use foo::{ + bar::{*, f}, + baz::{g, qux::{h, q::*<|>}} +}; + +fn qux(bar: Bar, baz: Baz) { + f(); + g(); + h(); + j(); +} +", + r" +mod foo { + pub mod bar { + pub struct Bar; + pub struct Baz; + pub struct Qux; + + pub fn f() {} + } + + pub mod baz { + pub fn g() {} + + pub mod qux { + pub fn h() {} + pub fn m() {} + + pub mod q { + pub fn j() {} + } + } + } +} + +use foo::{ + bar::{*, f}, + baz::{g, qux::{h, q::j}} +}; + +fn qux(bar: Bar, baz: Baz) { + f(); + g(); + h(); + j(); +} +", + ); } #[test] -- cgit v1.2.3 From bb72150f0214c9395c48fdd3ee93650f0a507112 Mon Sep 17 00:00:00 2001 From: unexge Date: Fri, 14 Aug 2020 22:10:49 +0300 Subject: Handle more cases in AST replacing in expand glob import --- crates/assists/src/handlers/expand_glob_import.rs | 253 +++++++++++++++++++--- crates/ide_db/src/defs.rs | 2 +- 2 files changed, 220 insertions(+), 35 deletions(-) diff --git a/crates/assists/src/handlers/expand_glob_import.rs b/crates/assists/src/handlers/expand_glob_import.rs index 0288d1c77..ff9c80d49 100644 --- a/crates/assists/src/handlers/expand_glob_import.rs +++ b/crates/assists/src/handlers/expand_glob_import.rs @@ -1,10 +1,12 @@ use either::Either; +use std::iter::successors; + use hir::{AssocItem, MacroDef, ModuleDef, Name, PathResolution, ScopeDef, SemanticsScope}; use ide_db::{ defs::{classify_name_ref, Definition, NameRefClass}, RootDatabase, }; -use syntax::{ast, AstNode, SyntaxToken, T}; +use syntax::{algo, ast, AstNode, SourceFile, SyntaxNode, SyntaxToken, T}; use crate::{ assist_context::{AssistBuilder, AssistContext, Assists}, @@ -48,27 +50,39 @@ pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Opti let scope = ctx.sema.scope_at_offset(source_file.syntax(), ctx.offset()); let defs_in_mod = find_defs_in_mod(ctx, scope, module)?; - let name_refs_in_source_file = - source_file.syntax().descendants().filter_map(ast::NameRef::cast).collect(); - let used_names = find_used_names(ctx, defs_in_mod, name_refs_in_source_file); + let names_to_import = find_names_to_import(ctx, source_file, defs_in_mod); - let target = parent.syntax(); + let target = parent.clone().either(|n| n.syntax().clone(), |n| n.syntax().clone()); acc.add( AssistId("expand_glob_import", AssistKind::RefactorRewrite), "Expand glob import", target.text_range(), |builder| { - replace_ast(builder, parent, mod_path, used_names); + replace_ast(builder, parent, mod_path, names_to_import); }, ) } -fn find_parent_and_path(star: &SyntaxToken) -> Option<(ast::UseTree, ast::Path)> { - star.ancestors().find_map(|n| { +fn find_parent_and_path( + star: &SyntaxToken, +) -> Option<(Either, ast::Path)> { + return star.ancestors().find_map(|n| { + find_use_tree_list(n.clone()) + .and_then(|(u, p)| Some((Either::Right(u), p))) + .or_else(|| find_use_tree(n).and_then(|(u, p)| Some((Either::Left(u), p)))) + }); + + fn find_use_tree_list(n: SyntaxNode) -> Option<(ast::UseTreeList, ast::Path)> { + let use_tree_list = ast::UseTreeList::cast(n)?; + let path = use_tree_list.parent_use_tree().path()?; + Some((use_tree_list, path)) + } + + fn find_use_tree(n: SyntaxNode) -> Option<(ast::UseTree, ast::Path)> { let use_tree = ast::UseTree::cast(n)?; let path = use_tree.path()?; Some((use_tree, path)) - }) + } } #[derive(PartialEq)] @@ -105,14 +119,36 @@ fn find_defs_in_mod( Some(defs) } -fn find_used_names( +fn find_names_to_import( ctx: &AssistContext, + source_file: &SourceFile, defs_in_mod: Vec, - name_refs_in_source_file: Vec, ) -> Vec { - let defs_in_source_file = name_refs_in_source_file - .iter() - .filter_map(|r| classify_name_ref(&ctx.sema, r)) + let (name_refs_in_use_item, name_refs_in_source) = source_file + .syntax() + .descendants() + .filter_map(|n| { + let name_ref = ast::NameRef::cast(n.clone())?; + let name_ref_class = classify_name_ref(&ctx.sema, &name_ref)?; + let is_in_use_item = + successors(n.parent(), |n| n.parent()).find_map(ast::Use::cast).is_some(); + Some((name_ref_class, is_in_use_item)) + }) + .partition::, _>(|&(_, is_in_use_item)| is_in_use_item); + + let name_refs_to_import: Vec = name_refs_in_source + .into_iter() + .filter_map(|(r, _)| { + if name_refs_in_use_item.contains(&(r.clone(), true)) { + // already imported + return None; + } + Some(r) + }) + .collect(); + + let defs_in_source_file = name_refs_to_import + .into_iter() .filter_map(|rc| match rc { NameRefClass::Definition(Definition::ModuleDef(def)) => Some(Def::ModuleDef(def)), NameRefClass::Definition(Definition::Macro(def)) => Some(Def::MacroDef(def)), @@ -141,28 +177,62 @@ fn find_used_names( fn replace_ast( builder: &mut AssistBuilder, - parent: ast::UseTree, + parent: Either, path: ast::Path, - used_names: Vec, + names_to_import: Vec, ) { - let replacement = match used_names.as_slice() { - [name] => ast::make::use_tree( - ast::make::path_from_text(&format!("{}::{}", path, name)), - None, - None, - false, - ), - names => ast::make::use_tree( - path, - Some(ast::make::use_tree_list(names.iter().map(|n| { - ast::make::use_tree(ast::make::path_from_text(&n.to_string()), None, None, false) - }))), - None, - false, - ), + let existing_use_trees = match parent.clone() { + Either::Left(_) => vec![], + Either::Right(u) => u.use_trees().filter(|n| + // filter out star + n.star_token().is_none() + ).collect(), }; - builder.replace_ast(parent, replacement); + let new_use_trees: Vec = names_to_import + .iter() + .map(|n| ast::make::use_tree(ast::make::path_from_text(&n.to_string()), None, None, false)) + .collect(); + + let use_trees = [&existing_use_trees[..], &new_use_trees[..]].concat(); + + match use_trees.as_slice() { + [name] => { + if let Some(end_path) = name.path() { + let replacement = ast::make::use_tree( + ast::make::path_from_text(&format!("{}::{}", path, end_path)), + None, + None, + false, + ); + + algo::diff( + &parent.either(|n| n.syntax().clone(), |n| n.syntax().clone()), + replacement.syntax(), + ) + .into_text_edit(builder.text_edit_builder()); + } + } + names => { + let replacement = match parent { + Either::Left(_) => ast::make::use_tree( + path, + Some(ast::make::use_tree_list(names.to_owned())), + None, + false, + ) + .syntax() + .clone(), + Either::Right(_) => ast::make::use_tree_list(names.to_owned()).syntax().clone(), + }; + + algo::diff( + &parent.either(|n| n.syntax().clone(), |n| n.syntax().clone()), + &replacement, + ) + .into_text_edit(builder.text_edit_builder()); + } + }; } #[cfg(test)] @@ -236,7 +306,46 @@ mod foo { pub fn f() {} } -use foo::{Baz, Bar, f}; +use foo::{f, Baz, Bar}; + +fn qux(bar: Bar, baz: Baz) { + f(); +} +", + ) + } + + #[test] + fn expanding_glob_import_with_existing_uses_in_same_module() { + check_assist( + expand_glob_import, + r" +mod foo { + pub struct Bar; + pub struct Baz; + pub struct Qux; + + pub fn f() {} +} + +use foo::Bar; +use foo::{*<|>, f}; + +fn qux(bar: Bar, baz: Baz) { + f(); +} +", + r" +mod foo { + pub struct Bar; + pub struct Baz; + pub struct Qux; + + pub fn f() {} +} + +use foo::Bar; +use foo::{f, Baz}; fn qux(bar: Bar, baz: Baz) { f(); @@ -286,7 +395,7 @@ mod foo { } } -use foo::{bar::{Baz, Bar, f}, baz::*}; +use foo::{bar::{f, Baz, Bar}, baz::*}; fn qux(bar: Bar, baz: Baz) { f(); @@ -486,6 +595,82 @@ use foo::{ baz::{g, qux::{h, q::j}} }; +fn qux(bar: Bar, baz: Baz) { + f(); + g(); + h(); + j(); +} +", + ); + + check_assist( + expand_glob_import, + r" +mod foo { + pub mod bar { + pub struct Bar; + pub struct Baz; + pub struct Qux; + + pub fn f() {} + } + + pub mod baz { + pub fn g() {} + + pub mod qux { + pub fn h() {} + pub fn m() {} + + pub mod q { + pub fn j() {} + } + } + } +} + +use foo::{ + bar::{*, f}, + baz::{g, qux::{q::j, *<|>}} +}; + +fn qux(bar: Bar, baz: Baz) { + f(); + g(); + h(); + j(); +} +", + r" +mod foo { + pub mod bar { + pub struct Bar; + pub struct Baz; + pub struct Qux; + + pub fn f() {} + } + + pub mod baz { + pub fn g() {} + + pub mod qux { + pub fn h() {} + pub fn m() {} + + pub mod q { + pub fn j() {} + } + } + } +} + +use foo::{ + bar::{*, f}, + baz::{g, qux::{q::j, h}} +}; + fn qux(bar: Bar, baz: Baz) { f(); g(); diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index 0d0affc27..1e7a1f159 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs @@ -225,7 +225,7 @@ pub fn classify_name(sema: &Semantics, name: &ast::Name) -> Option } } -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum NameRefClass { ExternCrate(Crate), Definition(Definition), -- cgit v1.2.3 From 11d048af03e0d9e07c5c67c9a644af5fbf94ed57 Mon Sep 17 00:00:00 2001 From: unexge Date: Fri, 14 Aug 2020 22:17:26 +0300 Subject: Run rustfmt --- crates/assists/src/handlers/expand_glob_import.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/assists/src/handlers/expand_glob_import.rs b/crates/assists/src/handlers/expand_glob_import.rs index ff9c80d49..f9a08e84e 100644 --- a/crates/assists/src/handlers/expand_glob_import.rs +++ b/crates/assists/src/handlers/expand_glob_import.rs @@ -183,10 +183,12 @@ fn replace_ast( ) { let existing_use_trees = match parent.clone() { Either::Left(_) => vec![], - Either::Right(u) => u.use_trees().filter(|n| + Either::Right(u) => u + .use_trees() + .filter(|n| // filter out star - n.star_token().is_none() - ).collect(), + n.star_token().is_none()) + .collect(), }; let new_use_trees: Vec = names_to_import -- cgit v1.2.3 From 0847bc801eab10ec32792fdc546007a8a1cfbdde Mon Sep 17 00:00:00 2001 From: unexge Date: Sun, 16 Aug 2020 16:25:10 +0300 Subject: Use `Definition::find_usages` for finding used items in expand glob import --- crates/assists/src/assist_context.rs | 4 - crates/assists/src/handlers/expand_glob_import.rs | 247 ++++++++++++---------- 2 files changed, 137 insertions(+), 114 deletions(-) diff --git a/crates/assists/src/assist_context.rs b/crates/assists/src/assist_context.rs index 11c171fc2..bf520069e 100644 --- a/crates/assists/src/assist_context.rs +++ b/crates/assists/src/assist_context.rs @@ -73,10 +73,6 @@ impl<'a> AssistContext<'a> { self.sema.db } - pub(crate) fn source_file(&self) -> &SourceFile { - &self.source_file - } - // NB, this ignores active selection. pub(crate) fn offset(&self) -> TextSize { self.frange.range.start() diff --git a/crates/assists/src/handlers/expand_glob_import.rs b/crates/assists/src/handlers/expand_glob_import.rs index f9a08e84e..64267a03f 100644 --- a/crates/assists/src/handlers/expand_glob_import.rs +++ b/crates/assists/src/handlers/expand_glob_import.rs @@ -1,12 +1,10 @@ use either::Either; -use std::iter::successors; - -use hir::{AssocItem, MacroDef, ModuleDef, Name, PathResolution, ScopeDef, SemanticsScope}; +use hir::{MacroDef, Module, ModuleDef, Name, PathResolution, ScopeDef, SemanticsScope}; use ide_db::{ defs::{classify_name_ref, Definition, NameRefClass}, - RootDatabase, + search::SearchScope, }; -use syntax::{algo, ast, AstNode, SourceFile, SyntaxNode, SyntaxToken, T}; +use syntax::{algo, ast, AstNode, Direction, SyntaxNode, SyntaxToken, T}; use crate::{ assist_context::{AssistBuilder, AssistContext, Assists}, @@ -41,16 +39,17 @@ use crate::{ pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { let star = ctx.find_token_at_offset(T![*])?; let (parent, mod_path) = find_parent_and_path(&star)?; - let module = match ctx.sema.resolve_path(&mod_path)? { + let target_module = match ctx.sema.resolve_path(&mod_path)? { PathResolution::Def(ModuleDef::Module(it)) => it, _ => return None, }; - let source_file = ctx.source_file(); - let scope = ctx.sema.scope_at_offset(source_file.syntax(), ctx.offset()); + let current_scope = ctx.sema.scope(&star.parent()); + let current_module = current_scope.module()?; - let defs_in_mod = find_defs_in_mod(ctx, scope, module)?; - let names_to_import = find_names_to_import(ctx, source_file, defs_in_mod); + let refs_in_target = find_refs_in_mod(ctx, target_module, Some(current_module))?; + let imported_defs = find_imported_defs(ctx, star)?; + let names_to_import = find_names_to_import(ctx, current_scope, refs_in_target, imported_defs); let target = parent.clone().either(|n| n.syntax().clone(), |n| n.syntax().clone()); acc.add( @@ -85,94 +84,119 @@ fn find_parent_and_path( } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq, Clone)] enum Def { ModuleDef(ModuleDef), MacroDef(MacroDef), } -impl Def { - fn name(&self, db: &RootDatabase) -> Option { - match self { - Def::ModuleDef(def) => def.name(db), - Def::MacroDef(def) => def.name(db), +#[derive(Debug, Clone)] +struct Ref { + // could be alias + visible_name: Name, + def: Def, +} + +impl Ref { + fn from_scope_def(name: Name, scope_def: ScopeDef) -> Option { + match scope_def { + ScopeDef::ModuleDef(def) => Some(Ref { visible_name: name, def: Def::ModuleDef(def) }), + ScopeDef::MacroDef(def) => Some(Ref { visible_name: name, def: Def::MacroDef(def) }), + _ => None, } } -} -fn find_defs_in_mod( - ctx: &AssistContext, - from: SemanticsScope<'_>, - module: hir::Module, -) -> Option> { - let module_scope = module.scope(ctx.db(), from.module()); - - let mut defs = vec![]; - for (_, def) in module_scope { - match def { - ScopeDef::ModuleDef(def) => defs.push(Def::ModuleDef(def)), - ScopeDef::MacroDef(def) => defs.push(Def::MacroDef(def)), - _ => continue, + fn is_referenced_in(&self, ctx: &AssistContext, scope: &SemanticsScope) -> bool { + let def = match self.def { + Def::ModuleDef(def) => Definition::ModuleDef(def), + Def::MacroDef(def) => Definition::Macro(def), + }; + + if let Definition::ModuleDef(ModuleDef::Trait(tr)) = def { + if scope + .traits_in_scope() + .into_iter() + .find(|other_tr_id| tr == other_tr_id.to_owned().into()) + .is_some() + { + return true; + } } + + let search_scope = SearchScope::single_file(ctx.frange.file_id); + !def.find_usages(&ctx.sema, Some(search_scope)).is_empty() + } +} + +#[derive(Debug, Clone)] +struct Refs(Vec); + +impl Refs { + fn used_refs(&self, ctx: &AssistContext, scope: &SemanticsScope) -> Refs { + Refs(self.0.clone().into_iter().filter(|r| r.is_referenced_in(ctx, scope)).collect()) } - Some(defs) + fn filter_out_by_defs(&self, defs: Vec) -> Refs { + Refs(self.0.clone().into_iter().filter(|r| !defs.contains(&r.def)).collect()) + } } -fn find_names_to_import( +fn find_refs_in_mod( ctx: &AssistContext, - source_file: &SourceFile, - defs_in_mod: Vec, -) -> Vec { - let (name_refs_in_use_item, name_refs_in_source) = source_file - .syntax() - .descendants() - .filter_map(|n| { - let name_ref = ast::NameRef::cast(n.clone())?; - let name_ref_class = classify_name_ref(&ctx.sema, &name_ref)?; - let is_in_use_item = - successors(n.parent(), |n| n.parent()).find_map(ast::Use::cast).is_some(); - Some((name_ref_class, is_in_use_item)) - }) - .partition::, _>(|&(_, is_in_use_item)| is_in_use_item); - - let name_refs_to_import: Vec = name_refs_in_source - .into_iter() - .filter_map(|(r, _)| { - if name_refs_in_use_item.contains(&(r.clone(), true)) { - // already imported - return None; - } - Some(r) - }) - .collect(); - - let defs_in_source_file = name_refs_to_import - .into_iter() - .filter_map(|rc| match rc { - NameRefClass::Definition(Definition::ModuleDef(def)) => Some(Def::ModuleDef(def)), - NameRefClass::Definition(Definition::Macro(def)) => Some(Def::MacroDef(def)), - _ => None, - }) - .collect::>(); + module: Module, + visible_from: Option, +) -> Option { + let module_scope = module.scope(ctx.db(), visible_from); + let refs = module_scope.into_iter().filter_map(|(n, d)| Ref::from_scope_def(n, d)).collect(); + Some(Refs(refs)) +} - defs_in_mod - .iter() - .filter(|def| { - if let Def::ModuleDef(ModuleDef::Trait(tr)) = def { - for item in tr.items(ctx.db()) { - if let AssocItem::Function(f) = item { - if defs_in_source_file.contains(&Def::ModuleDef(ModuleDef::Function(f))) { - return true; - } - } - } - } +// looks for name refs in parent use block's siblings +// +// mod bar { +// mod qux { +// struct Qux; +// } +// +// pub use qux::Qux; +// } +// +// ↓ --------------- +// use foo::*<|>; +// use baz::Baz; +// ↑ --------------- +fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option> { + let parent_use_item_syntax = + star.ancestors().find_map(|n| if ast::Use::can_cast(n.kind()) { Some(n) } else { None })?; + + Some( + [Direction::Prev, Direction::Next] + .iter() + .map(|dir| { + parent_use_item_syntax + .siblings(dir.to_owned()) + .filter(|n| ast::Use::can_cast(n.kind())) + }) + .flatten() + .filter_map(|n| Some(n.descendants().filter_map(ast::NameRef::cast))) + .flatten() + .filter_map(|r| match classify_name_ref(&ctx.sema, &r)? { + NameRefClass::Definition(Definition::ModuleDef(def)) => Some(Def::ModuleDef(def)), + NameRefClass::Definition(Definition::Macro(def)) => Some(Def::MacroDef(def)), + _ => None, + }) + .collect(), + ) +} - defs_in_source_file.contains(def) - }) - .filter_map(|d| d.name(ctx.db())) - .collect() +fn find_names_to_import( + ctx: &AssistContext, + current_scope: SemanticsScope, + refs_in_target: Refs, + imported_defs: Vec, +) -> Vec { + let used_refs = refs_in_target.used_refs(ctx, ¤t_scope).filter_out_by_defs(imported_defs); + used_refs.0.iter().map(|r| r.visible_name.clone()).collect() } fn replace_ast( @@ -685,34 +709,37 @@ fn qux(bar: Bar, baz: Baz) { #[test] fn expanding_glob_import_with_macro_defs() { - check_assist( - expand_glob_import, - r" -//- /lib.rs crate:foo -#[macro_export] -macro_rules! bar { - () => () -} - -pub fn baz() {} - -//- /main.rs crate:main deps:foo -use foo::*<|>; - -fn main() { - bar!(); - baz(); -} -", - r" -use foo::{bar, baz}; - -fn main() { - bar!(); - baz(); -} -", - ) + // TODO: this is currently fails because `Definition::find_usages` ignores macros + // https://github.com/rust-analyzer/rust-analyzer/issues/3484 + // + // check_assist( + // expand_glob_import, + // r" + // //- /lib.rs crate:foo + // #[macro_export] + // macro_rules! bar { + // () => () + // } + + // pub fn baz() {} + + // //- /main.rs crate:main deps:foo + // use foo::*<|>; + + // fn main() { + // bar!(); + // baz(); + // } + // ", + // r" + // use foo::{bar, baz}; + + // fn main() { + // bar!(); + // baz(); + // } + // ", + // ) } #[test] -- cgit v1.2.3 From 585f5d4901f3ddc0bec6aface8a86707d216886e Mon Sep 17 00:00:00 2001 From: unexge Date: Sun, 16 Aug 2020 16:42:44 +0300 Subject: Use fixme instead of todo --- crates/assists/src/handlers/expand_glob_import.rs | 2 +- crates/ide_db/src/defs.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/assists/src/handlers/expand_glob_import.rs b/crates/assists/src/handlers/expand_glob_import.rs index 64267a03f..0e80cde77 100644 --- a/crates/assists/src/handlers/expand_glob_import.rs +++ b/crates/assists/src/handlers/expand_glob_import.rs @@ -709,7 +709,7 @@ fn qux(bar: Bar, baz: Baz) { #[test] fn expanding_glob_import_with_macro_defs() { - // TODO: this is currently fails because `Definition::find_usages` ignores macros + // FIXME: this is currently fails because `Definition::find_usages` ignores macros // https://github.com/rust-analyzer/rust-analyzer/issues/3484 // // check_assist( diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index 1e7a1f159..0d0affc27 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs @@ -225,7 +225,7 @@ pub fn classify_name(sema: &Semantics, name: &ast::Name) -> Option } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug)] pub enum NameRefClass { ExternCrate(Crate), Definition(Definition), -- cgit v1.2.3 From 5d28dec7b93aad54866c80213358fb3eb28153be Mon Sep 17 00:00:00 2001 From: unexge Date: Sun, 16 Aug 2020 18:37:15 +0300 Subject: Fix importing unused traits in expand glob import --- crates/assists/src/handlers/expand_glob_import.rs | 101 ++++++++++++++++------ 1 file changed, 73 insertions(+), 28 deletions(-) diff --git a/crates/assists/src/handlers/expand_glob_import.rs b/crates/assists/src/handlers/expand_glob_import.rs index 0e80cde77..194fae63e 100644 --- a/crates/assists/src/handlers/expand_glob_import.rs +++ b/crates/assists/src/handlers/expand_glob_import.rs @@ -1,5 +1,5 @@ use either::Either; -use hir::{MacroDef, Module, ModuleDef, Name, PathResolution, ScopeDef, SemanticsScope}; +use hir::{AssocItem, MacroDef, Module, ModuleDef, Name, PathResolution, ScopeDef}; use ide_db::{ defs::{classify_name_ref, Definition, NameRefClass}, search::SearchScope, @@ -49,7 +49,7 @@ pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Opti let refs_in_target = find_refs_in_mod(ctx, target_module, Some(current_module))?; let imported_defs = find_imported_defs(ctx, star)?; - let names_to_import = find_names_to_import(ctx, current_scope, refs_in_target, imported_defs); + let names_to_import = find_names_to_import(ctx, refs_in_target, imported_defs); let target = parent.clone().either(|n| n.syntax().clone(), |n| n.syntax().clone()); acc.add( @@ -90,6 +90,18 @@ enum Def { MacroDef(MacroDef), } +impl Def { + fn is_referenced_in(&self, ctx: &AssistContext) -> bool { + let def = match self { + Def::ModuleDef(def) => Definition::ModuleDef(*def), + Def::MacroDef(def) => Definition::Macro(*def), + }; + + let search_scope = SearchScope::single_file(ctx.frange.file_id); + !def.find_usages(&ctx.sema, Some(search_scope)).is_empty() + } +} + #[derive(Debug, Clone)] struct Ref { // could be alias @@ -105,35 +117,39 @@ impl Ref { _ => None, } } - - fn is_referenced_in(&self, ctx: &AssistContext, scope: &SemanticsScope) -> bool { - let def = match self.def { - Def::ModuleDef(def) => Definition::ModuleDef(def), - Def::MacroDef(def) => Definition::Macro(def), - }; - - if let Definition::ModuleDef(ModuleDef::Trait(tr)) = def { - if scope - .traits_in_scope() - .into_iter() - .find(|other_tr_id| tr == other_tr_id.to_owned().into()) - .is_some() - { - return true; - } - } - - let search_scope = SearchScope::single_file(ctx.frange.file_id); - !def.find_usages(&ctx.sema, Some(search_scope)).is_empty() - } } #[derive(Debug, Clone)] struct Refs(Vec); impl Refs { - fn used_refs(&self, ctx: &AssistContext, scope: &SemanticsScope) -> Refs { - Refs(self.0.clone().into_iter().filter(|r| r.is_referenced_in(ctx, scope)).collect()) + fn used_refs(&self, ctx: &AssistContext) -> Refs { + Refs( + self.0 + .clone() + .into_iter() + .filter(|r| { + if let Def::ModuleDef(ModuleDef::Trait(tr)) = r.def { + if tr + .items(ctx.db()) + .into_iter() + .find(|ai| { + if let AssocItem::Function(f) = *ai { + Def::ModuleDef(ModuleDef::Function(f)).is_referenced_in(ctx) + } else { + false + } + }) + .is_some() + { + return true; + } + } + + r.def.is_referenced_in(ctx) + }) + .collect(), + ) } fn filter_out_by_defs(&self, defs: Vec) -> Refs { @@ -191,11 +207,10 @@ fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option fn find_names_to_import( ctx: &AssistContext, - current_scope: SemanticsScope, refs_in_target: Refs, imported_defs: Vec, ) -> Vec { - let used_refs = refs_in_target.used_refs(ctx, ¤t_scope).filter_out_by_defs(imported_defs); + let used_refs = refs_in_target.used_refs(ctx).filter_out_by_defs(imported_defs); used_refs.0.iter().map(|r| r.visible_name.clone()).collect() } @@ -767,7 +782,37 @@ fn main() { ().method(); } ", - ) + ); + + check_assist( + expand_glob_import, + r" +//- /lib.rs crate:foo +pub trait Tr { + fn method(&self) {} +} +impl Tr for () {} + +pub trait Tr2 { + fn method2(&self) {} +} +impl Tr2 for () {} + +//- /main.rs crate:main deps:foo +use foo::*<|>; + +fn main() { + ().method(); +} +", + r" +use foo::Tr; + +fn main() { + ().method(); +} +", + ); } #[test] -- cgit v1.2.3 From 5cff4b60bedf4d0b2e30d08aa19686584202a560 Mon Sep 17 00:00:00 2001 From: unexge Date: Mon, 17 Aug 2020 20:22:14 +0300 Subject: Fix importing private modules in expand glob import --- crates/assists/src/handlers/expand_glob_import.rs | 52 +++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/crates/assists/src/handlers/expand_glob_import.rs b/crates/assists/src/handlers/expand_glob_import.rs index 194fae63e..eb6dd68bb 100644 --- a/crates/assists/src/handlers/expand_glob_import.rs +++ b/crates/assists/src/handlers/expand_glob_import.rs @@ -162,11 +162,28 @@ fn find_refs_in_mod( module: Module, visible_from: Option, ) -> Option { + if let Some(from) = visible_from { + if !is_mod_visible_from(ctx, module, from) { + return None; + } + } + let module_scope = module.scope(ctx.db(), visible_from); let refs = module_scope.into_iter().filter_map(|(n, d)| Ref::from_scope_def(n, d)).collect(); Some(Refs(refs)) } +fn is_mod_visible_from(ctx: &AssistContext, module: Module, from: Module) -> bool { + match module.parent(ctx.db()) { + Some(parent) => { + parent.visibility_of(ctx.db(), &ModuleDef::Module(module)).map_or(true, |vis| { + vis.is_visible_from(ctx.db(), from.into()) && is_mod_visible_from(ctx, parent, from) + }) + } + None => true, + } +} + // looks for name refs in parent use block's siblings // // mod bar { @@ -815,6 +832,41 @@ fn main() { ); } + #[test] + fn expanding_is_not_applicable_if_target_module_is_not_accessible_from_current_scope() { + check_assist_not_applicable( + expand_glob_import, + r" +mod foo { + mod bar { + pub struct Bar; + } +} + +use foo::bar::*<|>; + +fn baz(bar: Bar) {} +", + ); + + check_assist_not_applicable( + expand_glob_import, + r" +mod foo { + mod bar { + pub mod baz { + pub struct Baz; + } + } +} + +use foo::bar::baz::*<|>; + +fn qux(baz: Baz) {} +", + ); + } + #[test] fn expanding_is_not_applicable_if_cursor_is_not_in_star_token() { check_assist_not_applicable( -- cgit v1.2.3 From ef54e8451d2ebe20e900f9bea4545795ebd035c7 Mon Sep 17 00:00:00 2001 From: unexge Date: Wed, 19 Aug 2020 20:16:03 +0300 Subject: Use new `Definition::usages` API in expand glob import --- crates/assists/src/handlers/expand_glob_import.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/assists/src/handlers/expand_glob_import.rs b/crates/assists/src/handlers/expand_glob_import.rs index eb6dd68bb..b39d040f6 100644 --- a/crates/assists/src/handlers/expand_glob_import.rs +++ b/crates/assists/src/handlers/expand_glob_import.rs @@ -98,7 +98,7 @@ impl Def { }; let search_scope = SearchScope::single_file(ctx.frange.file_id); - !def.find_usages(&ctx.sema, Some(search_scope)).is_empty() + def.usages(&ctx.sema).in_scope(search_scope).at_least_one() } } -- cgit v1.2.3 From 74ed42c8e9057bdd8910d0eba03ea0b30b87e660 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Fri, 21 Aug 2020 22:12:22 +0300 Subject: Gate stream.pipeline workaround on fixed versions of node --- editors/code/src/net.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/editors/code/src/net.ts b/editors/code/src/net.ts index 681eaa9c9..5eba2728d 100644 --- a/editors/code/src/net.ts +++ b/editors/code/src/net.ts @@ -134,6 +134,14 @@ async function downloadFile( await pipeline(srcStream, destFileStream); + // Don't apply the workaround in fixed versions of nodejs, since the process + // freezes on them, the process waits for no-longer emitted `close` event. + // The fix was applied in commit 7eed9d6bcc in v13.11.0 + // See the nodejs changelog: + // https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V13.md + const [, major, minor] = /v(\d+)\.(\d+)\.(\d+)/.exec(process.version)!; + if (+major > 13 || (+major === 13 && +minor >= 11)) return; + await new Promise(resolve => { destFileStream.on("close", resolve); destFileStream.destroy(); -- cgit v1.2.3 From cdd75a699aaa9dbf971a8c6b0d59b36c5b6b49e6 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 22 Aug 2020 22:03:02 +0300 Subject: Omit lenses for not runnable doctests --- crates/ide/src/completion.rs | 2 +- crates/ide/src/runnables.rs | 26 +++++++++++++++++++++++--- crates/syntax/src/algo.rs | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/crates/ide/src/completion.rs b/crates/ide/src/completion.rs index 25e580d80..33bed6991 100644 --- a/crates/ide/src/completion.rs +++ b/crates/ide/src/completion.rs @@ -92,7 +92,7 @@ pub use crate::completion::{ /// already present, it should give all possible variants for the identifier at /// the caret. In other words, for /// -/// ```no-run +/// ```no_run /// fn f() { /// let foo = 92; /// let _ = bar<|> diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 4139f329e..dd59d9e70 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -160,7 +160,7 @@ fn runnable_fn( RunnableKind::Test { test_id, attr } } else if fn_def.has_atom_attr("bench") { RunnableKind::Bench { test_id } - } else if has_doc_test(&fn_def) { + } else if has_runnable_doc_test(&fn_def) { RunnableKind::DocTest { test_id } } else { return None; @@ -211,8 +211,13 @@ fn has_test_related_attribute(fn_def: &ast::Fn) -> bool { .any(|attribute_text| attribute_text.contains("test")) } -fn has_doc_test(fn_def: &ast::Fn) -> bool { - fn_def.doc_comment_text().map_or(false, |comment| comment.contains("```")) +fn has_runnable_doc_test(fn_def: &ast::Fn) -> bool { + fn_def.doc_comment_text().map_or(false, |comments_text| { + comments_text.contains("```") + && !comments_text.contains("```ignore") + && !comments_text.contains("```no_run") + && !comments_text.contains("```compile_fail") + }) } fn runnable_mod( @@ -417,6 +422,21 @@ fn main() {} /// let x = 5; /// ``` fn foo() {} + +/// ```no_run +/// let z = 55; +/// ``` +fn should_have_no_runnable() {} + +/// ```ignore +/// let z = 55; +/// ``` +fn should_have_no_runnable_2() {} + +/// ```compile_fail +/// let z = 55; +/// ``` +fn should_have_no_runnable_3() {} "#, &[&BIN, &DOCTEST], expect![[r#" diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 6254b38ba..ea199f9b8 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs @@ -32,7 +32,7 @@ pub fn ancestors_at_offset( /// imprecise: if the cursor is strictly between two nodes of the desired type, /// as in /// -/// ```no-run +/// ```no_run /// struct Foo {}|struct Bar; /// ``` /// -- cgit v1.2.3 From 1d129a7172bbe502182be6cc3b50b3250cb6f3a9 Mon Sep 17 00:00:00 2001 From: dragfire Date: Sun, 23 Aug 2020 14:30:07 -0600 Subject: Invert if should be smart about is_some, is_none, is_ok, is_err --- crates/assists/src/handlers/invert_if.rs | 18 ++++++++++++++++++ crates/assists/src/utils.rs | 21 ++++++++++++++++++++- crates/syntax/src/ast/make.rs | 8 +++++++- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/crates/assists/src/handlers/invert_if.rs b/crates/assists/src/handlers/invert_if.rs index f0e047538..294256297 100644 --- a/crates/assists/src/handlers/invert_if.rs +++ b/crates/assists/src/handlers/invert_if.rs @@ -106,4 +106,22 @@ mod tests { "fn f() { i<|>f let Some(_) = Some(1) { 1 } else { 0 } }", ) } + + #[test] + fn invert_if_option_case() { + check_assist( + invert_if, + "fn f() { if<|> doc_style.is_some() { Class::DocComment } else { Class::Comment } }", + "fn f() { if doc_style.is_none() { Class::Comment } else { Class::DocComment } }", + ) + } + + #[test] + fn invert_if_result_case() { + check_assist( + invert_if, + "fn f() { i<|>f doc_style.is_err() { Class::Err } else { Class::Ok } }", + "fn f() { if doc_style.is_ok() { Class::Ok } else { Class::Err } }", + ) + } } diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index d071d6502..e15c982e7 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs @@ -11,7 +11,7 @@ use syntax::{ ast::{self, make, NameOwner}, AstNode, Direction, SyntaxKind::*, - SyntaxNode, TextSize, T, + SyntaxNode, SyntaxText, TextSize, T, }; use crate::assist_config::SnippetCap; @@ -179,6 +179,25 @@ fn invert_special_case(expr: &ast::Expr) -> Option { ast::BinOp::EqualityTest => bin.replace_op(T![!=]).map(|it| it.into()), _ => None, }, + ast::Expr::MethodCallExpr(mce) => { + const IS_SOME_TEXT: &str = "is_some"; + const IS_NONE_TEXT: &str = "is_none"; + const IS_OK_TEXT: &str = "is_ok"; + const IS_ERR_TEXT: &str = "is_err"; + + let name = mce.name_ref()?; + let name_text = name.text(); + + let caller = || -> Option { Some(mce.receiver()?.syntax().text()) }; + + match name_text { + x if x == IS_SOME_TEXT => make::expr_method_call(IS_NONE_TEXT, caller), + x if x == IS_NONE_TEXT => make::expr_method_call(IS_SOME_TEXT, caller), + x if x == IS_OK_TEXT => make::expr_method_call(IS_ERR_TEXT, caller), + x if x == IS_ERR_TEXT => make::expr_method_call(IS_OK_TEXT, caller), + _ => None, + } + } ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::PrefixOp::Not => pe.expr(), // FIXME: // ast::Expr::Literal(true | false ) diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index d20c085aa..7958721e2 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs @@ -7,7 +7,7 @@ use itertools::Itertools; use stdx::format_to; -use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken}; +use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxText, SyntaxToken}; pub fn name(text: &str) -> ast::Name { ast_from_text(&format!("mod {};", text)) @@ -137,6 +137,12 @@ pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::Expr { pub fn expr_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr { expr_from_text(&format!("{}{}", f, arg_list)) } +pub fn expr_method_call(text: &str, caller: F) -> Option +where + F: FnOnce() -> Option, +{ + try_expr_from_text(&format!("{}.{}()", caller()?, text)) +} fn expr_from_text(text: &str) -> ast::Expr { ast_from_text(&format!("const C: () = {};", text)) } -- cgit v1.2.3 From a8fa5cd42e3cfa131121a46b289ee919e495316e Mon Sep 17 00:00:00 2001 From: Pavan Kumar Sunkara Date: Mon, 24 Aug 2020 10:25:19 +0200 Subject: Add version to deps in cargo.toml --- crates/assists/Cargo.toml | 16 ++++++++-------- crates/base_db/Cargo.toml | 14 +++++++------- crates/cfg/Cargo.toml | 2 +- crates/flycheck/Cargo.toml | 2 +- crates/hir/Cargo.toml | 14 +++++++------- crates/hir_def/Cargo.toml | 20 ++++++++++---------- crates/hir_expand/Cargo.toml | 16 ++++++++-------- crates/hir_ty/Cargo.toml | 16 ++++++++-------- crates/ide/Cargo.toml | 22 +++++++++++----------- crates/ide_db/Cargo.toml | 14 +++++++------- crates/mbe/Cargo.toml | 6 +++--- crates/proc_macro_api/Cargo.toml | 2 +- crates/proc_macro_srv/Cargo.toml | 8 ++++---- crates/profile/Cargo.toml | 2 +- crates/project_model/Cargo.toml | 14 +++++++------- crates/rust-analyzer/Cargo.toml | 1 + crates/ssr/Cargo.toml | 12 ++++++------ crates/syntax/Cargo.toml | 6 +++--- crates/test_utils/Cargo.toml | 2 +- crates/tt/Cargo.toml | 2 +- crates/vfs-notify/Cargo.toml | 4 ++-- crates/vfs/Cargo.toml | 2 +- 22 files changed, 99 insertions(+), 98 deletions(-) diff --git a/crates/assists/Cargo.toml b/crates/assists/Cargo.toml index a560a35c7..aab901684 100644 --- a/crates/assists/Cargo.toml +++ b/crates/assists/Cargo.toml @@ -13,11 +13,11 @@ rustc-hash = "1.1.0" itertools = "0.9.0" either = "1.5.3" -stdx = { path = "../stdx" } -syntax = { path = "../syntax" } -text_edit = { path = "../text_edit" } -profile = { path = "../profile" } -base_db = { path = "../base_db" } -ide_db = { path = "../ide_db" } -hir = { path = "../hir" } -test_utils = { path = "../test_utils" } +stdx = { path = "../stdx", version = "0.0.0" } +syntax = { path = "../syntax", version = "0.0.0" } +text_edit = { path = "../text_edit", version = "0.0.0" } +profile = { path = "../profile", version = "0.0.0" } +base_db = { path = "../base_db", version = "0.0.0" } +ide_db = { path = "../ide_db", version = "0.0.0" } +hir = { path = "../hir", version = "0.0.0" } +test_utils = { path = "../test_utils", version = "0.0.0" } diff --git a/crates/base_db/Cargo.toml b/crates/base_db/Cargo.toml index 7347d7528..c343b22ee 100644 --- a/crates/base_db/Cargo.toml +++ b/crates/base_db/Cargo.toml @@ -12,10 +12,10 @@ doctest = false salsa = "0.15.2" rustc-hash = "1.1.0" -syntax = { path = "../syntax" } -cfg = { path = "../cfg" } -profile = { path = "../profile" } -tt = { path = "../tt" } -test_utils = { path = "../test_utils" } -vfs = { path = "../vfs" } -stdx = { path = "../stdx" } +syntax = { path = "../syntax", version = "0.0.0" } +cfg = { path = "../cfg", version = "0.0.0" } +profile = { path = "../profile", version = "0.0.0" } +tt = { path = "../tt", version = "0.0.0" } +test_utils = { path = "../test_utils", version = "0.0.0" } +vfs = { path = "../vfs", version = "0.0.0" } +stdx = { path = "../stdx", version = "0.0.0" } diff --git a/crates/cfg/Cargo.toml b/crates/cfg/Cargo.toml index d2ea551d1..573a69a1c 100644 --- a/crates/cfg/Cargo.toml +++ b/crates/cfg/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] rustc-hash = "1.1.0" -tt = { path = "../tt" } +tt = { path = "../tt", version = "0.0.0" } [dev-dependencies] mbe = { path = "../mbe" } diff --git a/crates/flycheck/Cargo.toml b/crates/flycheck/Cargo.toml index 262a66e4e..32f026727 100644 --- a/crates/flycheck/Cargo.toml +++ b/crates/flycheck/Cargo.toml @@ -15,4 +15,4 @@ cargo_metadata = "0.11.1" serde_json = "1.0.48" jod-thread = "0.1.1" -toolchain = { path = "../toolchain" } +toolchain = { path = "../toolchain", version = "0.0.0" } diff --git a/crates/hir/Cargo.toml b/crates/hir/Cargo.toml index dbb2986b6..4b5221f60 100644 --- a/crates/hir/Cargo.toml +++ b/crates/hir/Cargo.toml @@ -15,10 +15,10 @@ either = "1.5.3" arrayvec = "0.5.1" itertools = "0.9.0" -stdx = { path = "../stdx" } -syntax = { path = "../syntax" } -base_db = { path = "../base_db" } -profile = { path = "../profile" } -hir_expand = { path = "../hir_expand" } -hir_def = { path = "../hir_def" } -hir_ty = { path = "../hir_ty" } +stdx = { path = "../stdx", version = "0.0.0" } +syntax = { path = "../syntax", version = "0.0.0" } +base_db = { path = "../base_db", version = "0.0.0" } +profile = { path = "../profile", version = "0.0.0" } +hir_expand = { path = "../hir_expand", version = "0.0.0" } +hir_def = { path = "../hir_def", version = "0.0.0" } +hir_ty = { path = "../hir_ty", version = "0.0.0" } diff --git a/crates/hir_def/Cargo.toml b/crates/hir_def/Cargo.toml index 57745322f..cba5fbb27 100644 --- a/crates/hir_def/Cargo.toml +++ b/crates/hir_def/Cargo.toml @@ -20,16 +20,16 @@ itertools = "0.9.0" indexmap = "1.4.0" smallvec = "1.4.0" -stdx = { path = "../stdx" } -arena = { path = "../arena" } -base_db = { path = "../base_db" } -syntax = { path = "../syntax" } -profile = { path = "../profile" } -hir_expand = { path = "../hir_expand" } -test_utils = { path = "../test_utils" } -mbe = { path = "../mbe" } -cfg = { path = "../cfg" } -tt = { path = "../tt" } +stdx = { path = "../stdx", version = "0.0.0" } +arena = { path = "../arena", version = "0.0.0" } +base_db = { path = "../base_db", version = "0.0.0" } +syntax = { path = "../syntax", version = "0.0.0" } +profile = { path = "../profile", version = "0.0.0" } +hir_expand = { path = "../hir_expand", version = "0.0.0" } +test_utils = { path = "../test_utils", version = "0.0.0" } +mbe = { path = "../mbe", version = "0.0.0" } +cfg = { path = "../cfg", version = "0.0.0" } +tt = { path = "../tt", version = "0.0.0" } [dev-dependencies] expect-test = "0.1" diff --git a/crates/hir_expand/Cargo.toml b/crates/hir_expand/Cargo.toml index 1c4699291..30378f5e0 100644 --- a/crates/hir_expand/Cargo.toml +++ b/crates/hir_expand/Cargo.toml @@ -13,11 +13,11 @@ log = "0.4.8" either = "1.5.3" rustc-hash = "1.0.0" -arena = { path = "../arena" } -base_db = { path = "../base_db" } -syntax = { path = "../syntax" } -parser = { path = "../parser" } -profile = { path = "../profile" } -tt = { path = "../tt" } -mbe = { path = "../mbe" } -test_utils = { path = "../test_utils"} +arena = { path = "../arena", version = "0.0.0" } +base_db = { path = "../base_db", version = "0.0.0" } +syntax = { path = "../syntax", version = "0.0.0" } +parser = { path = "../parser", version = "0.0.0" } +profile = { path = "../profile", version = "0.0.0" } +tt = { path = "../tt", version = "0.0.0" } +mbe = { path = "../mbe", version = "0.0.0" } +test_utils = { path = "../test_utils", version = "0.0.0" } diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml index 06da0d0ec..701fc0f9d 100644 --- a/crates/hir_ty/Cargo.toml +++ b/crates/hir_ty/Cargo.toml @@ -20,14 +20,14 @@ chalk-solve = { version = "0.23.0" } chalk-ir = { version = "0.23.0" } chalk-recursive = { version = "0.23.0" } -stdx = { path = "../stdx" } -hir_def = { path = "../hir_def" } -hir_expand = { path = "../hir_expand" } -arena = { path = "../arena" } -base_db = { path = "../base_db" } -profile = { path = "../profile" } -syntax = { path = "../syntax" } -test_utils = { path = "../test_utils" } +stdx = { path = "../stdx", version = "0.0.0" } +hir_def = { path = "../hir_def", version = "0.0.0" } +hir_expand = { path = "../hir_expand", version = "0.0.0" } +arena = { path = "../arena", version = "0.0.0" } +base_db = { path = "../base_db", version = "0.0.0" } +profile = { path = "../profile", version = "0.0.0" } +syntax = { path = "../syntax", version = "0.0.0" } +test_utils = { path = "../test_utils", version = "0.0.0" } [dev-dependencies] expect-test = "0.1" diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml index 700944430..688401098 100644 --- a/crates/ide/Cargo.toml +++ b/crates/ide/Cargo.toml @@ -16,20 +16,20 @@ log = "0.4.8" rustc-hash = "1.1.0" oorandom = "11.1.2" -stdx = { path = "../stdx" } -syntax = { path = "../syntax" } -text_edit = { path = "../text_edit" } -base_db = { path = "../base_db" } -ide_db = { path = "../ide_db" } -cfg = { path = "../cfg" } -profile = { path = "../profile" } -test_utils = { path = "../test_utils" } -assists = { path = "../assists" } -ssr = { path = "../ssr" } +stdx = { path = "../stdx", version = "0.0.0" } +syntax = { path = "../syntax", version = "0.0.0" } +text_edit = { path = "../text_edit", version = "0.0.0" } +base_db = { path = "../base_db", version = "0.0.0" } +ide_db = { path = "../ide_db", version = "0.0.0" } +cfg = { path = "../cfg", version = "0.0.0" } +profile = { path = "../profile", version = "0.0.0" } +test_utils = { path = "../test_utils", version = "0.0.0" } +assists = { path = "../assists", version = "0.0.0" } +ssr = { path = "../ssr", version = "0.0.0" } # ide should depend only on the top-level `hir` package. if you need # something from some `hir_xxx` subpackage, reexport the API via `hir`. -hir = { path = "../hir" } +hir = { path = "../hir", version = "0.0.0" } [dev-dependencies] expect-test = "0.1" diff --git a/crates/ide_db/Cargo.toml b/crates/ide_db/Cargo.toml index 692fb6415..2230013df 100644 --- a/crates/ide_db/Cargo.toml +++ b/crates/ide_db/Cargo.toml @@ -19,12 +19,12 @@ rustc-hash = "1.1.0" once_cell = "1.3.1" either = "1.5.3" -stdx = { path = "../stdx" } -syntax = { path = "../syntax" } -text_edit = { path = "../text_edit" } -base_db = { path = "../base_db" } -profile = { path = "../profile" } -test_utils = { path = "../test_utils" } +stdx = { path = "../stdx", version = "0.0.0" } +syntax = { path = "../syntax", version = "0.0.0" } +text_edit = { path = "../text_edit", version = "0.0.0" } +base_db = { path = "../base_db", version = "0.0.0" } +profile = { path = "../profile", version = "0.0.0" } +test_utils = { path = "../test_utils", version = "0.0.0" } # ide should depend only on the top-level `hir` package. if you need # something from some `hir_xxx` subpackage, reexport the API via `hir`. -hir = { path = "../hir" } +hir = { path = "../hir", version = "0.0.0" } diff --git a/crates/mbe/Cargo.toml b/crates/mbe/Cargo.toml index 1aba8b7c4..ecd917792 100644 --- a/crates/mbe/Cargo.toml +++ b/crates/mbe/Cargo.toml @@ -13,9 +13,9 @@ rustc-hash = "1.1.0" smallvec = "1.2.0" log = "0.4.8" -syntax = { path = "../syntax" } -parser = { path = "../parser" } -tt = { path = "../tt" } +syntax = { path = "../syntax", version = "0.0.0" } +parser = { path = "../parser", version = "0.0.0" } +tt = { path = "../tt", version = "0.0.0" } [dev-dependencies] test_utils = { path = "../test_utils" } diff --git a/crates/proc_macro_api/Cargo.toml b/crates/proc_macro_api/Cargo.toml index a3a4c1103..cc6019c91 100644 --- a/crates/proc_macro_api/Cargo.toml +++ b/crates/proc_macro_api/Cargo.toml @@ -15,4 +15,4 @@ log = "0.4.8" crossbeam-channel = "0.4.0" jod-thread = "0.1.1" -tt = { path = "../tt" } +tt = { path = "../tt", version = "0.0.0" } diff --git a/crates/proc_macro_srv/Cargo.toml b/crates/proc_macro_srv/Cargo.toml index a468b5560..700d2c0f7 100644 --- a/crates/proc_macro_srv/Cargo.toml +++ b/crates/proc_macro_srv/Cargo.toml @@ -13,10 +13,10 @@ goblin = "0.2.1" libloading = "0.6.0" memmap = "0.7" -tt = { path = "../tt" } -mbe = { path = "../mbe" } -proc_macro_api = { path = "../proc_macro_api" } -test_utils = { path = "../test_utils" } +tt = { path = "../tt", version = "0.0.0" } +mbe = { path = "../mbe", version = "0.0.0" } +proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" } +test_utils = { path = "../test_utils", version = "0.0.0" } [dev-dependencies] cargo_metadata = "0.11.1" diff --git a/crates/profile/Cargo.toml b/crates/profile/Cargo.toml index e271e3a56..17769fcd3 100644 --- a/crates/profile/Cargo.toml +++ b/crates/profile/Cargo.toml @@ -14,7 +14,7 @@ cfg-if = "0.1.10" libc = "0.2.73" backtrace = { version = "0.3.44", optional = true } -arena = { path = "../arena" } +arena = { path = "../arena", version = "0.0.0" } [target.'cfg(target_os = "linux")'.dependencies] perf-event = "0.4" diff --git a/crates/project_model/Cargo.toml b/crates/project_model/Cargo.toml index 386f72f41..53db7d3b9 100644 --- a/crates/project_model/Cargo.toml +++ b/crates/project_model/Cargo.toml @@ -16,10 +16,10 @@ serde = { version = "1.0.106", features = ["derive"] } serde_json = "1.0.48" anyhow = "1.0.26" -arena = { path = "../arena" } -cfg = { path = "../cfg" } -base_db = { path = "../base_db" } -toolchain = { path = "../toolchain" } -proc_macro_api = { path = "../proc_macro_api" } -paths = { path = "../paths" } -stdx = { path = "../stdx" } +arena = { path = "../arena", version = "0.0.0" } +cfg = { path = "../cfg", version = "0.0.0" } +base_db = { path = "../base_db", version = "0.0.0" } +toolchain = { path = "../toolchain", version = "0.0.0" } +proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" } +paths = { path = "../paths", version = "0.0.0" } +stdx = { path = "../stdx", version = "0.0.0" } diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 068a961dc..7e280b1f7 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -5,6 +5,7 @@ license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] autobins = false edition = "2018" +publish = false [lib] doctest = false diff --git a/crates/ssr/Cargo.toml b/crates/ssr/Cargo.toml index 22b6af0fa..6f0f53d70 100644 --- a/crates/ssr/Cargo.toml +++ b/crates/ssr/Cargo.toml @@ -14,12 +14,12 @@ doctest = false rustc-hash = "1.1.0" itertools = "0.9.0" -text_edit = { path = "../text_edit" } -syntax = { path = "../syntax" } -base_db = { path = "../base_db" } -ide_db = { path = "../ide_db" } -hir = { path = "../hir" } -test_utils = { path = "../test_utils" } +text_edit = { path = "../text_edit", version = "0.0.0" } +syntax = { path = "../syntax", version = "0.0.0" } +base_db = { path = "../base_db", version = "0.0.0" } +ide_db = { path = "../ide_db", version = "0.0.0" } +hir = { path = "../hir", version = "0.0.0" } +test_utils = { path = "../test_utils", version = "0.0.0" } [dev-dependencies] expect-test = "0.1" diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index 6818f3ad8..2c1bdb295 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml @@ -23,9 +23,9 @@ once_cell = "1.3.1" smol_str = { version = "0.1.15", features = ["serde"] } serde = { version = "1.0.106", features = ["derive"] } -stdx = { path = "../stdx" } -text_edit = { path = "../text_edit" } -parser = { path = "../parser" } +stdx = { path = "../stdx", version = "0.0.0" } +text_edit = { path = "../text_edit", version = "0.0.0" } +parser = { path = "../parser", version = "0.0.0" } [dev-dependencies] walkdir = "2.3.1" diff --git a/crates/test_utils/Cargo.toml b/crates/test_utils/Cargo.toml index 45e5fb97f..d60b88add 100644 --- a/crates/test_utils/Cargo.toml +++ b/crates/test_utils/Cargo.toml @@ -15,4 +15,4 @@ text-size = "1.0.0" serde_json = "1.0.48" rustc-hash = "1.1.0" -stdx = { path = "../stdx" } +stdx = { path = "../stdx", version = "0.0.0" } diff --git a/crates/tt/Cargo.toml b/crates/tt/Cargo.toml index dfcdcf03e..bf7e3f21f 100644 --- a/crates/tt/Cargo.toml +++ b/crates/tt/Cargo.toml @@ -13,4 +13,4 @@ doctest = false # to reduce number of compilations smol_str = { version = "0.1.15", features = ["serde"] } -stdx = { path = "../stdx" } +stdx = { path = "../stdx", version = "0.0.0" } diff --git a/crates/vfs-notify/Cargo.toml b/crates/vfs-notify/Cargo.toml index c1e53f4b1..304c9883f 100644 --- a/crates/vfs-notify/Cargo.toml +++ b/crates/vfs-notify/Cargo.toml @@ -16,5 +16,5 @@ walkdir = "2.3.1" crossbeam-channel = "0.4.0" notify = "5.0.0-pre.3" -vfs = { path = "../vfs" } -paths = { path = "../paths" } +vfs = { path = "../vfs", version = "0.0.0" } +paths = { path = "../paths", version = "0.0.0" } diff --git a/crates/vfs/Cargo.toml b/crates/vfs/Cargo.toml index 9ae8f19b6..a88d69a5e 100644 --- a/crates/vfs/Cargo.toml +++ b/crates/vfs/Cargo.toml @@ -12,4 +12,4 @@ doctest = false rustc-hash = "1.0" fst = "0.4" -paths = { path = "../paths" } +paths = { path = "../paths", version = "0.0.0" } -- cgit v1.2.3 From d7ece3028de09f30af4384726eca1eff2cd52dff Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 24 Aug 2020 12:19:12 +0200 Subject: Add Early Return rule to style --- docs/dev/style.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/docs/dev/style.md b/docs/dev/style.md index 44f0956c2..bb7a351f3 100644 --- a/docs/dev/style.md +++ b/docs/dev/style.md @@ -181,6 +181,30 @@ fn frobnicate(walrus: Option) { } ``` +# Early Returns + +Do use early returns + +```rust +// Good +fn foo() -> Option { + if !condition() { + return None; + } + + Some(...) +} + +// Not as good +fn foo() -> Option { + if condition() { + Some(...) + } else { + None + } +} +``` + # Getters & Setters If a field can have any value without breaking invariants, make the field public. @@ -189,7 +213,7 @@ Never provide setters. Getters should return borrowed data: -``` +```rust struct Person { // Invariant: never empty first_name: String, -- cgit v1.2.3 From fc3e591bdb28745ef29e90de2c1625e6d4e4a229 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 24 Aug 2020 12:49:36 +0200 Subject: Avoid monomorphization --- docs/dev/style.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/docs/dev/style.md b/docs/dev/style.md index 44f0956c2..ae69cf1a7 100644 --- a/docs/dev/style.md +++ b/docs/dev/style.md @@ -231,6 +231,41 @@ if words.len() != 2 { } ``` +# Avoid Monomorphization + +Rust uses monomorphization to compile generic code, meaning that for each instantiation of a generic functions with concrete types, the function is compiled afresh, *per crate*. +This allows for exceptionally good performance, but leads to increased compile times. +Runtime performance obeys 80%/20% rule -- only a small fraction of code is hot. +Compile time **does not** obey this rule -- all code has to be compiled. +For this reason, avoid making a lot of code type parametric, *especially* on the boundaries between crates. + +```rust +// Good +fn frbonicate(f: impl FnMut()) { + frobnicate_impl(&mut f) +} +fn frobnicate_impl(f: &mut dyn FnMut()) { + // lots of code +} + +// Not as good +fn frbonicate(f: impl FnMut()) { + // lots of code +} +``` + +Avoid `AsRef` polymorphism, it pays back only for widely used libraries: + +```rust +// Good +fn frbonicate(f: &Path) { +} + +// Not as good +fn frbonicate(f: impl AsRef) { +} +``` + # Documentation For `.md` and `.adoc` files, prefer a sentence-per-line format, don't wrap lines. -- cgit v1.2.3 From 35fd9a8e0ba7013cf95996bfc9221ebe91d3db75 Mon Sep 17 00:00:00 2001 From: Pavan Kumar Sunkara Date: Sat, 6 Jun 2020 21:50:28 +0200 Subject: Added weekly publish workflow --- .github/workflows/publish.yml | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..be2c7a8ca --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,44 @@ +name: publish +on: + workflow_dispatch: # We can add version input when 1.0 is released and scheduled releases are removed + + schedule: + - cron: "0 0 * * *" # midnight UTC + + push: + branches: + - release + +jobs: + publish: + name: publish + runs-on: ubuntu-16.04 + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Install Rust toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + override: true + + - name: Install cargo-workspaces + uses: actions-rs/install@v0.1 + with: + crate: cargo-workspaces + + - name: Release + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + PATCH: ${{ github.run_number }} + shell: bash + run: | + git config --global user.email "runner@gha.local" + git config --global user.name "Github Action" + rm Cargo.lock + cargo workspaces rename ra_ap_%n + cargo workspaces publish --yes --force '*' --exact --no-git-commit --allow-dirty --skip-published custom 0.0.$PATCH -- cgit v1.2.3 From 335add49dbd98c13a8dd2b0284cefda00da13ec9 Mon Sep 17 00:00:00 2001 From: Pavan Kumar Sunkara Date: Mon, 24 Aug 2020 13:06:30 +0200 Subject: Add description for crates that will be published --- crates/assists/Cargo.toml | 1 + crates/base_db/Cargo.toml | 1 + crates/cfg/Cargo.toml | 1 + crates/flycheck/Cargo.toml | 1 + crates/hir/Cargo.toml | 1 + crates/hir_def/Cargo.toml | 1 + crates/hir_expand/Cargo.toml | 1 + crates/hir_ty/Cargo.toml | 1 + crates/ide/Cargo.toml | 1 + crates/ide_db/Cargo.toml | 1 + crates/mbe/Cargo.toml | 1 + crates/parser/Cargo.toml | 1 + crates/paths/Cargo.toml | 1 + crates/proc_macro_api/Cargo.toml | 1 + crates/proc_macro_srv/Cargo.toml | 1 + crates/proc_macro_test/Cargo.toml | 1 + crates/profile/Cargo.toml | 1 + crates/project_model/Cargo.toml | 1 + crates/stdx/Cargo.toml | 1 + crates/test_utils/Cargo.toml | 1 + crates/text_edit/Cargo.toml | 1 + crates/toolchain/Cargo.toml | 1 + crates/tt/Cargo.toml | 1 + crates/vfs-notify/Cargo.toml | 1 + crates/vfs/Cargo.toml | 1 + 25 files changed, 25 insertions(+) diff --git a/crates/assists/Cargo.toml b/crates/assists/Cargo.toml index aab901684..264125651 100644 --- a/crates/assists/Cargo.toml +++ b/crates/assists/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "assists" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/base_db/Cargo.toml b/crates/base_db/Cargo.toml index c343b22ee..f7bfcb0d7 100644 --- a/crates/base_db/Cargo.toml +++ b/crates/base_db/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "base_db" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/cfg/Cargo.toml b/crates/cfg/Cargo.toml index 573a69a1c..a6785ee8e 100644 --- a/crates/cfg/Cargo.toml +++ b/crates/cfg/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "cfg" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/flycheck/Cargo.toml b/crates/flycheck/Cargo.toml index 32f026727..c230fc1e2 100644 --- a/crates/flycheck/Cargo.toml +++ b/crates/flycheck/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "flycheck" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/hir/Cargo.toml b/crates/hir/Cargo.toml index 4b5221f60..60a48170e 100644 --- a/crates/hir/Cargo.toml +++ b/crates/hir/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "hir" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/hir_def/Cargo.toml b/crates/hir_def/Cargo.toml index cba5fbb27..011e4612c 100644 --- a/crates/hir_def/Cargo.toml +++ b/crates/hir_def/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "hir_def" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/hir_expand/Cargo.toml b/crates/hir_expand/Cargo.toml index 30378f5e0..9fad2ab94 100644 --- a/crates/hir_expand/Cargo.toml +++ b/crates/hir_expand/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "hir_expand" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml index 701fc0f9d..33e155a70 100644 --- a/crates/hir_ty/Cargo.toml +++ b/crates/hir_ty/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "hir_ty" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml index 688401098..336e9d2aa 100644 --- a/crates/ide/Cargo.toml +++ b/crates/ide/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "ide" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/ide_db/Cargo.toml b/crates/ide_db/Cargo.toml index 2230013df..320fb15e5 100644 --- a/crates/ide_db/Cargo.toml +++ b/crates/ide_db/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "ide_db" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/mbe/Cargo.toml b/crates/mbe/Cargo.toml index ecd917792..af80e2be3 100644 --- a/crates/mbe/Cargo.toml +++ b/crates/mbe/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "mbe" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index 358be92d1..1610e0d23 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "parser" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/paths/Cargo.toml b/crates/paths/Cargo.toml index 5ac18d63b..da26938c1 100644 --- a/crates/paths/Cargo.toml +++ b/crates/paths/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "paths" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/proc_macro_api/Cargo.toml b/crates/proc_macro_api/Cargo.toml index cc6019c91..75f67a22e 100644 --- a/crates/proc_macro_api/Cargo.toml +++ b/crates/proc_macro_api/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "proc_macro_api" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/proc_macro_srv/Cargo.toml b/crates/proc_macro_srv/Cargo.toml index 700d2c0f7..fb84e04ae 100644 --- a/crates/proc_macro_srv/Cargo.toml +++ b/crates/proc_macro_srv/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "proc_macro_srv" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/proc_macro_test/Cargo.toml b/crates/proc_macro_test/Cargo.toml index 7b0f64f31..753443be2 100644 --- a/crates/proc_macro_test/Cargo.toml +++ b/crates/proc_macro_test/Cargo.toml @@ -4,6 +4,7 @@ version = "0.0.0" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" +publish = false [lib] doctest = false diff --git a/crates/profile/Cargo.toml b/crates/profile/Cargo.toml index 17769fcd3..261172d61 100644 --- a/crates/profile/Cargo.toml +++ b/crates/profile/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "profile" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/project_model/Cargo.toml b/crates/project_model/Cargo.toml index 53db7d3b9..8bee398d9 100644 --- a/crates/project_model/Cargo.toml +++ b/crates/project_model/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "project_model" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/stdx/Cargo.toml b/crates/stdx/Cargo.toml index b186b46f2..8d7a51156 100644 --- a/crates/stdx/Cargo.toml +++ b/crates/stdx/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "stdx" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/test_utils/Cargo.toml b/crates/test_utils/Cargo.toml index d60b88add..93eecc678 100644 --- a/crates/test_utils/Cargo.toml +++ b/crates/test_utils/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "test_utils" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/text_edit/Cargo.toml b/crates/text_edit/Cargo.toml index a69b1ef2b..8aadc1875 100644 --- a/crates/text_edit/Cargo.toml +++ b/crates/text_edit/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "text_edit" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/toolchain/Cargo.toml b/crates/toolchain/Cargo.toml index 4856668f8..dcf0bfca0 100644 --- a/crates/toolchain/Cargo.toml +++ b/crates/toolchain/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "toolchain" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/tt/Cargo.toml b/crates/tt/Cargo.toml index bf7e3f21f..5b8972ea3 100644 --- a/crates/tt/Cargo.toml +++ b/crates/tt/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "tt" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/vfs-notify/Cargo.toml b/crates/vfs-notify/Cargo.toml index 304c9883f..54b51faab 100644 --- a/crates/vfs-notify/Cargo.toml +++ b/crates/vfs-notify/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "vfs-notify" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" diff --git a/crates/vfs/Cargo.toml b/crates/vfs/Cargo.toml index a88d69a5e..c318a68f7 100644 --- a/crates/vfs/Cargo.toml +++ b/crates/vfs/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "vfs" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" -- cgit v1.2.3 From 63f63acc7caddd0613eca98940b6c5fb5678f951 Mon Sep 17 00:00:00 2001 From: Pavan Kumar Sunkara Date: Mon, 24 Aug 2020 13:29:10 +0200 Subject: Add TBD description to arena --- crates/arena/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/arena/Cargo.toml b/crates/arena/Cargo.toml index f2bb5cc45..863eedf76 100644 --- a/crates/arena/Cargo.toml +++ b/crates/arena/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "arena" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" -- cgit v1.2.3 From b2d43daeb4c22a3792c948fb46c1e6fd4c1d3de2 Mon Sep 17 00:00:00 2001 From: Pavan Kumar Sunkara Date: Mon, 24 Aug 2020 17:27:13 +0200 Subject: Allow rust-analyzer auto publishing --- crates/rust-analyzer/Cargo.toml | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 7e280b1f7..044686a99 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "rust-analyzer" version = "0.0.0" +description = "TBD" license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] autobins = false edition = "2018" -publish = false [lib] doctest = false @@ -33,26 +33,26 @@ rayon = "1.3.1" mimalloc = { version = "0.1.19", default-features = false, optional = true } lsp-server = "0.3.3" -stdx = { path = "../stdx" } -flycheck = { path = "../flycheck" } -ide = { path = "../ide" } -profile = { path = "../profile" } -project_model = { path = "../project_model" } -syntax = { path = "../syntax" } -text_edit = { path = "../text_edit" } -vfs = { path = "../vfs" } -vfs-notify = { path = "../vfs-notify" } -cfg = { path = "../cfg" } -toolchain = { path = "../toolchain" } +stdx = { path = "../stdx", version = "0.0.0" } +flycheck = { path = "../flycheck", version = "0.0.0" } +ide = { path = "../ide", version = "0.0.0" } +profile = { path = "../profile", version = "0.0.0" } +project_model = { path = "../project_model", version = "0.0.0" } +syntax = { path = "../syntax", version = "0.0.0" } +text_edit = { path = "../text_edit", version = "0.0.0" } +vfs = { path = "../vfs", version = "0.0.0" } +vfs-notify = { path = "../vfs-notify", version = "0.0.0" } +cfg = { path = "../cfg", version = "0.0.0" } +toolchain = { path = "../toolchain", version = "0.0.0" } # This should only be used in CLI -base_db = { path = "../base_db" } -ide_db = { path = "../ide_db" } -ssr = { path = "../ssr" } -hir = { path = "../hir" } -hir_def = { path = "../hir_def" } -hir_ty = { path = "../hir_ty" } -proc_macro_srv = { path = "../proc_macro_srv" } +base_db = { path = "../base_db", version = "0.0.0" } +ide_db = { path = "../ide_db", version = "0.0.0" } +ssr = { path = "../ssr", version = "0.0.0" } +hir = { path = "../hir", version = "0.0.0" } +hir_def = { path = "../hir_def", version = "0.0.0" } +hir_ty = { path = "../hir_ty", version = "0.0.0" } +proc_macro_srv = { path = "../proc_macro_srv", version = "0.0.0" } [target.'cfg(windows)'.dependencies] winapi = "0.3.8" -- cgit v1.2.3 From f3ac19e8cd8be78f1eb96893482edac038739bb1 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 24 Aug 2020 22:02:55 +0200 Subject: Support extern types --- Cargo.lock | 4 +- crates/hir_def/src/item_tree/lower.rs | 4 + crates/hir_def/src/nameres/tests.rs | 2 + crates/syntax/src/ast/generated/nodes.rs | 8 +- xtask/Cargo.toml | 2 +- xtask/src/codegen/rust.ungram | 587 ------------------------------- 6 files changed, 16 insertions(+), 591 deletions(-) delete mode 100644 xtask/src/codegen/rust.ungram diff --git a/Cargo.lock b/Cargo.lock index 46d9469c0..69affa0ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1688,9 +1688,9 @@ dependencies = [ [[package]] name = "ungrammar" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab6142ac77be714b1ea78faca6efaed5478c50724786b0fe80d8528d10692b3" +checksum = "ca4d39065b45f658d33013f7cc93ee050708cd543f6e07dd15b4293fcf217e12" [[package]] name = "unicode-bidi" diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 391ab5d39..6a503d785 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -557,6 +557,10 @@ impl Ctx { let statik = self.lower_static(&ast)?; statik.into() } + ast::ExternItem::TypeAlias(ty) => { + let id = self.lower_type_alias(&ty)?; + id.into() + } ast::ExternItem::MacroCall(_) => return None, }; self.add_attrs(id.into(), attrs); diff --git a/crates/hir_def/src/nameres/tests.rs b/crates/hir_def/src/nameres/tests.rs index 8aaf7a158..5ca30dac9 100644 --- a/crates/hir_def/src/nameres/tests.rs +++ b/crates/hir_def/src/nameres/tests.rs @@ -46,6 +46,7 @@ union U { to_be: bool, not_to_be: u8 } enum E { V } extern { + type Ext; static EXT: u8; fn ext(); } @@ -65,6 +66,7 @@ extern { Baz: t v E: t EXT: v + Ext: t U: t ext: v "#]], diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 6317407c6..d6af5755c 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs @@ -1380,6 +1380,7 @@ pub enum ExternItem { Fn(Fn), MacroCall(MacroCall), Static(Static), + TypeAlias(TypeAlias), } impl ast::AttrsOwner for ExternItem {} impl ast::NameOwner for ExternItem {} @@ -3339,10 +3340,13 @@ impl From for ExternItem { impl From for ExternItem { fn from(node: Static) -> ExternItem { ExternItem::Static(node) } } +impl From for ExternItem { + fn from(node: TypeAlias) -> ExternItem { ExternItem::TypeAlias(node) } +} impl AstNode for ExternItem { fn can_cast(kind: SyntaxKind) -> bool { match kind { - FN | MACRO_CALL | STATIC => true, + FN | MACRO_CALL | STATIC | TYPE_ALIAS => true, _ => false, } } @@ -3351,6 +3355,7 @@ impl AstNode for ExternItem { FN => ExternItem::Fn(Fn { syntax }), MACRO_CALL => ExternItem::MacroCall(MacroCall { syntax }), STATIC => ExternItem::Static(Static { syntax }), + TYPE_ALIAS => ExternItem::TypeAlias(TypeAlias { syntax }), _ => return None, }; Some(res) @@ -3360,6 +3365,7 @@ impl AstNode for ExternItem { ExternItem::Fn(it) => &it.syntax, ExternItem::MacroCall(it) => &it.syntax, ExternItem::Static(it) => &it.syntax, + ExternItem::TypeAlias(it) => &it.syntax, } } } diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index e9edbdd10..0750b5657 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -15,7 +15,7 @@ flate2 = "1.0" pico-args = "0.3.1" proc-macro2 = "1.0.8" quote = "1.0.2" -ungrammar = "1.1.1" +ungrammar = "1.1.3" walkdir = "2.3.1" write-json = "0.1.0" # Avoid adding more dependencies to this crate diff --git a/xtask/src/codegen/rust.ungram b/xtask/src/codegen/rust.ungram deleted file mode 100644 index aca23890c..000000000 --- a/xtask/src/codegen/rust.ungram +++ /dev/null @@ -1,587 +0,0 @@ -//*************************// -// Names, Paths and Macros // -//*************************// - -Name = - 'ident' - -NameRef = - 'ident' | 'int_number' - -Path = - (qualifier:Path '::')? segment:PathSegment - -PathSegment = - 'crate' | 'self' | 'super' -| '::' NameRef -| NameRef GenericArgList? -| NameRef ParamList RetType? -| '<' PathType ('as' PathType)? '>' - -GenericArgList = - '::'? '<' (GenericArg (',' GenericArg)* ','?)? '>' - -GenericArg = - TypeArg -| AssocTypeArg -| LifetimeArg -| ConstArg - -TypeArg = - Type - -AssocTypeArg = - NameRef (':' TypeBoundList | '=' Type) - -LifetimeArg = - 'lifetime' - -ConstArg = - Expr - -MacroCall = - Attr* Path '!' Name? TokenTree ';'? - -TokenTree = - '(' ')' -| '{' '}' -| '[' ']' - -MacroItems = - Item* - -MacroStmts = - statements:Stmt* - Expr? - -//*************************// -// Items // -//*************************// - -SourceFile = - 'shebang'? - Attr* - Item* - -Item = - Const -| Enum -| ExternBlock -| ExternCrate -| Fn -| Impl -| MacroCall -| Module -| Static -| Struct -| Trait -| TypeAlias -| Union -| Use - -Module = - Attr* Visibility? 'mod' Name - (ItemList | ';') - -ItemList = - '{' Attr* Item* '}' - -ExternCrate = - Attr* Visibility? 'extern' 'crate' (NameRef | 'self') Rename? ';' - -Rename = - 'as' (Name | '_') - -Use = - Attr* Visibility? 'use' UseTree ';' - -UseTree = - (Path? '::')? ('*' | UseTreeList ) -| Path Rename? - -UseTreeList = - '{' (UseTree (',' UseTree)* ','?)? '}' - -Fn = - Attr* Visibility? - 'default'? ('async' | 'const')? 'unsafe'? Abi? - 'fn' Name GenericParamList? ParamList RetType? - WhereClause? - (body:BlockExpr | ';') - -Abi = - 'extern' 'string'? - -ParamList = - '('( - SelfParam - | (SelfParam ',')? (Param (',' Param)* ','?)? - )')' - -SelfParam = - Attr* ( - ('&' 'lifetime'?)? 'mut'? 'self' - | 'mut'? 'self' ':' Type - ) - -Param = - Attr* ( - Pat (':' Type) - | Type - | '...' - ) - -RetType = - '->' Type - -TypeAlias = - Attr* Visibility? 'default'? 'type' Name GenericParamList? (':' TypeBoundList?)? WhereClause? - '=' Type ';' - -Struct = - Attr* Visibility? 'struct' Name GenericParamList? ( - WhereClause? (RecordFieldList | ';') - | TupleFieldList WhereClause? ';' - ) - -RecordFieldList = - '{' fields:(RecordField (',' RecordField)* ','?)? '}' - -RecordField = - Attr* Visibility? Name ':' Type - -TupleFieldList = - '(' fields:(TupleField (',' TupleField)* ','?)? ')' - -TupleField = - Attr* Visibility? Type - -FieldList = - RecordFieldList -| TupleFieldList - -Enum = - Attr* Visibility? 'enum' Name GenericParamList? WhereClause? - VariantList - -VariantList = - '{' (Variant (',' Variant)* ','?)? '}' - -Variant = - Attr* Visibility? Name FieldList ('=' Expr)? - -Union = - Attr* Visibility? 'union' Name GenericParamList? WhereClause? - RecordFieldList - -AdtDef = - Enum -| Struct -| Union - -Const = - Attr* Visibility? 'default'? 'const' (Name | '_') ':' Type - '=' body:Expr ';' - -Static = - Attr* Visibility? 'static'? 'mut'? Name ':' Type - '=' body:Expr ';' - -Trait = - Attr* Visibility? 'unsafe'? 'auto'? 'trait' Name GenericParamList - (':' TypeBoundList?)? WhereClause - AssocItemList - -AssocItemList = - '{' Attr* AssocItem* '}' - -AssocItem = - Const -| Fn -| MacroCall -| TypeAlias - -Impl = - Attr* Visibility? - 'default'? 'unsafe'? 'impl' 'const'? GenericParamList? - ('!'? target_trait:Type 'for')? target_type:Type - WhereClause? - AssocItemList - -ExternBlock = - Attr* Abi ExternItemList - -ExternItemList = - '{' Attr* ExternItem* '}' - -ExternItem = - Fn | Static | MacroCall - -GenericParamList = - '<' (GenericParam (',' GenericParam)* ','?)? '>' - -GenericParam = - ConstParam -| LifetimeParam -| TypeParam - -TypeParam = - Attr* Name (':' TypeBoundList?)? - ('=' default_type:Type)? - -ConstParam = - Attr* 'const' Name ':' Type - ('=' default_val:Expr)? - -LifetimeParam = - Attr* 'lifetime' (':' TypeBoundList?)? - -WhereClause = - 'where' predicates:(WherePred (',' WherePred)* ','?) - -WherePred = - ('for' GenericParamList)? ('lifetime' | Type) ':' TypeBoundList - -Visibility = - 'pub' ('(' - 'super' - | 'self' - | 'crate' - | 'in' Path - ')')? - -Attr = - '#' '!'? '[' Path ('=' Literal | TokenTree)? ']' - -//****************************// -// Statements and Expressions // -//****************************// - -Stmt = - ExprStmt -| Item -| LetStmt - -LetStmt = - Attr* 'let' Pat (':' Type)? - '=' initializer:Expr ';' - -ExprStmt = - Attr* Expr ';'? - -Expr = - ArrayExpr -| AwaitExpr -| BinExpr -| BlockExpr -| BoxExpr -| BreakExpr -| CallExpr -| CastExpr -| ClosureExpr -| ContinueExpr -| EffectExpr -| FieldExpr -| ForExpr -| IfExpr -| IndexExpr -| Literal -| LoopExpr -| MacroCall -| MatchExpr -| MethodCallExpr -| ParenExpr -| PathExpr -| PrefixExpr -| RangeExpr -| RecordExpr -| RefExpr -| ReturnExpr -| TryExpr -| TupleExpr -| WhileExpr - -Literal = - Attr* value:( - 'int_number' | 'float_number' - | 'string' | 'raw_string' - | 'byte_string' | 'raw_byte_string' - | 'true' | 'false' - | 'char' | 'byte' - ) - -PathExpr = - Attr* Path - -BlockExpr = - '{' - Attr* - statements:Stmt* - Expr? - '}' - -RefExpr = - Attr* '&' ('raw' |'mut' | 'const') Expr - -TryExpr = - Attr* Expr '?' - -EffectExpr = - Attr* Label? ('try' | 'unsafe' | 'async') BlockExpr - -PrefixExpr = - Attr* op:('-' | '!' | '*') Expr - -BinExpr = - Attr* - lhs:Expr - op:( - '||' | '&&' - | '==' | '!=' | '<=' | '>=' | '<' | '>' - | '+' | '*' | '-' | '/' | '%' | '<<' | '>>' | '^' | '|' | '&' - | '=' | '+=' | '/=' | '*=' | '%=' | '>>=' | '<<=' | '-=' | '|=' | '&=' | '^=' - ) - rhs:Expr - -CastExpr = - Attr* Expr 'as' Type - -ParenExpr = - Attr* '(' Attr* Expr ')' - -ArrayExpr = - Attr* '[' Attr* ( - (Expr (',' Expr)* ','?)? - | Expr ';' Expr - ) ']' - -IndexExpr = - Attr* base:Expr '[' index:Expr ']' - -TupleExpr = - Attr* '(' Attr* fields:(Expr (',' Expr)* ','?)? ')' - -RecordExpr = - Path RecordExprFieldList - -RecordExprFieldList = - '{' - Attr* - fields:(RecordExprField (',' RecordExprField)* ','?) - ('..' spread:Expr)? - '}' - -RecordExprField = - Attr* NameRef (':' Expr)? - -CallExpr = - Attr* Expr ArgList - -ArgList = - '(' args:(Expr (',' Expr)* ','?)? ')' - -MethodCallExpr = - Attr* Expr '.' NameRef GenericArgList? ArgList - -FieldExpr = - Attr* Expr '.' NameRef - -ClosureExpr = - Attr* 'static'? 'async'? 'move'? ParamList RetType? - body:Expr - -IfExpr = - Attr* 'if' Condition then_branch:BlockExpr - ('else' else_branch:(IfExpr | BlockExpr))? - -Condition = - 'let' Pat '=' Expr -| Expr - -LoopExpr = - Attr* Label? 'loop' - loop_body:BlockExpr - -ForExpr = - Attr* Label? 'for' Pat 'in' iterable:Expr - loop_body:BlockExpr - -WhileExpr = - Attr* Label? 'while' Condition - loop_body:BlockExpr - -Label = - 'lifetime' - -BreakExpr = - Attr* 'break' 'lifetime'? Expr? - -ContinueExpr = - Attr* 'continue' 'lifetime'? - -RangeExpr = - Attr* start:Expr? op:('..' | '..=') end:Expr? - -MatchExpr = - Attr* 'match' Expr MatchArmList - -MatchArmList = - '{' - Attr* - arms:MatchArm* - '}' - -MatchArm = - Attr* Pat guard:MatchGuard? '=>' Expr ','? - -MatchGuard = - 'if' Expr - -ReturnExpr = - Attr* 'return' Expr? - -AwaitExpr = - Attr* Expr '.' 'await' - -BoxExpr = - Attr* 'box' Expr - -//*************************// -// Types // -//*************************// - -Type = - ArrayType -| DynTraitType -| FnPointerType -| ForType -| ImplTraitType -| InferType -| NeverType -| ParenType -| PathType -| PointerType -| ReferenceType -| SliceType -| TupleType - -ParenType = - '(' Type ')' - -NeverType = - '!' - -PathType = - Path - -TupleType = - '(' fields:(Type (',' Type)* ','?)? ')' - -PointerType = - '*' ('const' | 'mut') Type - -ReferenceType = - '&' 'lifetime'? 'mut'? Type - -ArrayType = - '[' Type ';' Expr ']' - -SliceType = - '[' Type ']' - -InferType = - '_' - -FnPointerType = - 'const'? 'async'? 'unsafe'? Abi? 'fn' ParamList RetType? - -ForType = - 'for' GenericParamList Type - -ImplTraitType = - 'impl' TypeBoundList - -DynTraitType = - 'dyn' TypeBoundList - -TypeBoundList = - bounds:(TypeBound ('+' TypeBound)* '+'?) - -TypeBound = - 'lifetime' -| '?'? Type - -//************************// -// Patterns // -//************************// - -Pat = - IdentPat -| BoxPat -| RestPat -| LiteralPat -| MacroPat -| OrPat -| ParenPat -| PathPat -| WildcardPat -| RangePat -| RecordPat -| RefPat -| SlicePat -| TuplePat -| TupleStructPat - -LiteralPat = - Literal - -IdentPat = - Attr* 'ref'? 'mut'? Name ('@' Pat)? - -WildcardPat = - '_' - -RangePat = - start:Pat op:('..' | '..=') end:Pat - -RefPat = - '&' 'mut'? Pat - -RecordPat = - Path RecordPatFieldList - -RecordPatFieldList = - '{' - fields:(RecordPatField (',' RecordPatField)* ','?) - '..'? - '}' - -RecordPatField = - Attr* (NameRef ':')? Pat - -TupleStructPat = - Path '(' fields:(Pat (',' Pat)* ','?)? ')' - -TuplePat = - '(' fields:(Pat (',' Pat)* ','?)? ')' - -ParenPat = - '(' Pat ')' - -SlicePat = - '[' (Pat (',' Pat)* ','?)? ']' - -PathPat = - Path - -OrPat = - (Pat ('|' Pat)* '|'?) - -BoxPat = - 'box' Pat - -RestPat = - '..' - -MacroPat = - MacroCall -- cgit v1.2.3