aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock8
-rw-r--r--crates/assists/src/handlers/generate_impl.rs2
-rw-r--r--crates/assists/src/handlers/generate_new.rs2
-rw-r--r--crates/assists/src/handlers/introduce_named_lifetime.rs21
-rw-r--r--crates/completion/src/completions/unqualified_path.rs19
-rw-r--r--crates/hir/src/code_model.rs41
-rw-r--r--crates/hir/src/db.rs4
-rw-r--r--crates/hir/src/from_id.rs6
-rw-r--r--crates/hir/src/has_source.rs10
-rw-r--r--crates/hir/src/lib.rs2
-rw-r--r--crates/hir/src/semantics.rs23
-rw-r--r--crates/hir/src/semantics/source_to_def.rs4
-rw-r--r--crates/hir_def/src/adt.rs47
-rw-r--r--crates/hir_def/src/attr.rs146
-rw-r--r--crates/hir_def/src/body.rs17
-rw-r--r--crates/hir_def/src/body/lower.rs33
-rw-r--r--crates/hir_def/src/data.rs5
-rw-r--r--crates/hir_def/src/db.rs7
-rw-r--r--crates/hir_def/src/generics.rs9
-rw-r--r--crates/hir_def/src/item_scope.rs2
-rw-r--r--crates/hir_def/src/item_tree.rs43
-rw-r--r--crates/hir_def/src/item_tree/lower.rs53
-rw-r--r--crates/hir_def/src/lang_item.rs77
-rw-r--r--crates/hir_def/src/lib.rs30
-rw-r--r--crates/hir_def/src/nameres/collector.rs121
-rw-r--r--crates/hir_def/src/nameres/tests/macros.rs31
-rw-r--r--crates/hir_def/src/path/lower.rs4
-rw-r--r--crates/hir_def/src/type_ref.rs10
-rw-r--r--crates/hir_expand/src/builtin_derive.rs40
-rw-r--r--crates/hir_expand/src/builtin_macro.rs27
-rw-r--r--crates/hir_expand/src/db.rs5
-rw-r--r--crates/hir_expand/src/hygiene.rs4
-rw-r--r--crates/hir_expand/src/lib.rs15
-rw-r--r--crates/hir_expand/src/name.rs5
-rw-r--r--crates/hir_ty/src/diagnostics.rs15
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs103
-rw-r--r--crates/hir_ty/src/tests/macros.rs6
-rw-r--r--crates/ide/src/display/navigation_target.rs65
-rw-r--r--crates/ide/src/doc_links.rs7
-rw-r--r--crates/ide/src/extend_selection.rs2
-rw-r--r--crates/ide/src/goto_definition.rs57
-rw-r--r--crates/ide/src/goto_implementation.rs8
-rw-r--r--crates/ide/src/hover.rs4
-rw-r--r--crates/ide/src/lib.rs7
-rw-r--r--crates/ide/src/references.rs91
-rw-r--r--crates/ide/src/references/rename.rs104
-rw-r--r--crates/ide/src/runnables.rs203
-rw-r--r--crates/ide/src/syntax_highlighting.rs1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlighting.html5
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs3
-rw-r--r--crates/ide_db/src/apply_change.rs1
-rw-r--r--crates/ide_db/src/defs.rs61
-rw-r--r--crates/ide_db/src/search.rs63
-rw-r--r--crates/ide_db/src/symbol_index.rs3
-rw-r--r--crates/mbe/src/mbe_expander/matcher.rs2
-rw-r--r--crates/mbe/src/subtree_source.rs8
-rw-r--r--crates/mbe/src/syntax_bridge.rs4
-rw-r--r--crates/parser/src/grammar.rs7
-rw-r--r--crates/parser/src/grammar/expressions/atom.rs16
-rw-r--r--crates/parser/src/grammar/items/traits.rs10
-rw-r--r--crates/parser/src/grammar/params.rs13
-rw-r--r--crates/parser/src/grammar/type_args.rs4
-rw-r--r--crates/parser/src/grammar/type_params.rs18
-rw-r--r--crates/parser/src/grammar/types.rs4
-rw-r--r--crates/parser/src/syntax_kind/generated.rs5
-rw-r--r--crates/project_model/src/cargo_workspace.rs31
-rw-r--r--crates/rust-analyzer/Cargo.toml2
-rw-r--r--crates/rust-analyzer/src/caps.rs3
-rw-r--r--crates/rust-analyzer/src/handlers.rs2
-rw-r--r--crates/rust-analyzer/src/to_proto.rs5
-rw-r--r--crates/syntax/src/ast.rs6
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs98
-rw-r--r--crates/syntax/src/ast/node_ext.rs66
-rw-r--r--crates/syntax/src/display.rs18
-rw-r--r--crates/syntax/src/parsing/lexer.rs4
-rw-r--r--crates/syntax/test_data/lexer/err/0057_lifetime_starts_with_a_number.rs (renamed from crates/syntax/test_data/lexer/err/0057_lifetime_strarts_with_a_number.rs)0
-rw-r--r--crates/syntax/test_data/lexer/err/0057_lifetime_starts_with_a_number.txt (renamed from crates/syntax/test_data/lexer/err/0057_lifetime_strarts_with_a_number.txt)4
-rw-r--r--crates/syntax/test_data/lexer/ok/0007_lifetimes.txt8
-rw-r--r--crates/syntax/test_data/parser/err/0024_many_type_parens.rast22
-rw-r--r--crates/syntax/test_data/parser/err/0027_incomplere_where_for.rast3
-rw-r--r--crates/syntax/test_data/parser/err/0043_weird_blocks.rast3
-rw-r--r--crates/syntax/test_data/parser/err/0044_unexpected_for_type.rast45
-rw-r--r--crates/syntax/test_data/parser/err/0046_ambiguous_trait_object.rast9
-rw-r--r--crates/syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast3
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0003_where_pred_for.rast6
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0006_self_param.rast6
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0007_type_param_bounds.rast3
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0015_continue_expr.rast3
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0028_impl_trait_type.rast6
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0033_reference_type;.rast3
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0034_break_expr.rast6
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0039_type_arg.rast3
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast3
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.rast6
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0056_where_clause.rast18
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0065_dyn_trait_type.rast6
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0081_for_type.rast15
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0109_label.rast9
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast6
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0161_labeled_block.rast3
-rw-r--r--crates/syntax/test_data/parser/ok/0018_struct_type_params.rast51
-rw-r--r--crates/syntax/test_data/parser/ok/0020_type_param_bounds.rast42
-rw-r--r--crates/syntax/test_data/parser/ok/0032_where_for.rast6
-rw-r--r--crates/syntax/test_data/parser/ok/0033_label_break.rast21
-rw-r--r--crates/syntax/test_data/parser/ok/0035_weird_exprs.rast19
-rw-r--r--crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast18
-rw-r--r--crates/syntax/test_data/parser/ok/0067_where_for_pred.rast45
-rw-r--r--crates/syntax/test_data/parser/ok/0069_multi_trait_object.rast9
-rw-r--r--docs/dev/README.md14
-rw-r--r--editors/code/package-lock.json71
-rw-r--r--editors/code/package.json6
-rw-r--r--xtask/Cargo.toml4
-rw-r--r--xtask/src/ast_src.rs3
-rw-r--r--xtask/src/codegen/gen_syntax.rs2
114 files changed, 1648 insertions, 870 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ff2c33f45..31a850797 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -844,9 +844,9 @@ dependencies = [
844 844
845[[package]] 845[[package]]
846name = "lsp-types" 846name = "lsp-types"
847version = "0.85.0" 847version = "0.86.0"
848source = "registry+https://github.com/rust-lang/crates.io-index" 848source = "registry+https://github.com/rust-lang/crates.io-index"
849checksum = "857650f3e83fb62f89d15410414e0ed7d0735445020da398d37f65d20a5423b9" 849checksum = "f2a5c40d566f2704dac30859bca152217583fc94fd5b178d8baba915e1abd382"
850dependencies = [ 850dependencies = [
851 "base64", 851 "base64",
852 "bitflags", 852 "bitflags",
@@ -1827,9 +1827,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
1827 1827
1828[[package]] 1828[[package]]
1829name = "ungrammar" 1829name = "ungrammar"
1830version = "1.2.2" 1830version = "1.4.0"
1831source = "registry+https://github.com/rust-lang/crates.io-index" 1831source = "registry+https://github.com/rust-lang/crates.io-index"
1832checksum = "873186a460627379e7e28880a0d33b729c205634f6f021321f50b323235e62d7" 1832checksum = "68951379f3ced25754472ca5addbf74d7dab58c9818f49290a3d8caa3ab44fb7"
1833 1833
1834[[package]] 1834[[package]]
1835name = "unicase" 1835name = "unicase"
diff --git a/crates/assists/src/handlers/generate_impl.rs b/crates/assists/src/handlers/generate_impl.rs
index 114974465..960af5ab3 100644
--- a/crates/assists/src/handlers/generate_impl.rs
+++ b/crates/assists/src/handlers/generate_impl.rs
@@ -53,7 +53,7 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()
53 if let Some(type_params) = type_params { 53 if let Some(type_params) = type_params {
54 let lifetime_params = type_params 54 let lifetime_params = type_params
55 .lifetime_params() 55 .lifetime_params()
56 .filter_map(|it| it.lifetime_token()) 56 .filter_map(|it| it.lifetime())
57 .map(|it| it.text().clone()); 57 .map(|it| it.text().clone());
58 let type_params = type_params 58 let type_params = type_params
59 .type_params() 59 .type_params()
diff --git a/crates/assists/src/handlers/generate_new.rs b/crates/assists/src/handlers/generate_new.rs
index 7db10f276..c5fec4e0a 100644
--- a/crates/assists/src/handlers/generate_new.rs
+++ b/crates/assists/src/handlers/generate_new.rs
@@ -99,7 +99,7 @@ fn generate_impl_text(strukt: &ast::Struct, code: &str) -> String {
99 if let Some(type_params) = type_params { 99 if let Some(type_params) = type_params {
100 let lifetime_params = type_params 100 let lifetime_params = type_params
101 .lifetime_params() 101 .lifetime_params()
102 .filter_map(|it| it.lifetime_token()) 102 .filter_map(|it| it.lifetime())
103 .map(|it| it.text().clone()); 103 .map(|it| it.text().clone());
104 let type_params = 104 let type_params =
105 type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone()); 105 type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone());
diff --git a/crates/assists/src/handlers/introduce_named_lifetime.rs b/crates/assists/src/handlers/introduce_named_lifetime.rs
index 4cc8dae65..ab8fe3ea9 100644
--- a/crates/assists/src/handlers/introduce_named_lifetime.rs
+++ b/crates/assists/src/handlers/introduce_named_lifetime.rs
@@ -1,7 +1,7 @@
1use rustc_hash::FxHashSet; 1use rustc_hash::FxHashSet;
2use syntax::{ 2use syntax::{
3 ast::{self, GenericParamsOwner, NameOwner}, 3 ast::{self, GenericParamsOwner, NameOwner},
4 AstNode, SyntaxKind, TextRange, TextSize, 4 AstNode, TextRange, TextSize,
5}; 5};
6 6
7use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists}; 7use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
@@ -35,13 +35,12 @@ static ASSIST_LABEL: &str = "Introduce named lifetime";
35// FIXME: How can we handle renaming any one of multiple anonymous lifetimes? 35// FIXME: How can we handle renaming any one of multiple anonymous lifetimes?
36// FIXME: should also add support for the case fun(f: &Foo) -> &<|>Foo 36// FIXME: should also add support for the case fun(f: &Foo) -> &<|>Foo
37pub(crate) fn introduce_named_lifetime(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 37pub(crate) fn introduce_named_lifetime(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
38 let lifetime_token = ctx 38 let lifetime =
39 .find_token_syntax_at_offset(SyntaxKind::LIFETIME) 39 ctx.find_node_at_offset::<ast::Lifetime>().filter(|lifetime| lifetime.text() == "'_")?;
40 .filter(|lifetime| lifetime.text() == "'_")?; 40 if let Some(fn_def) = lifetime.syntax().ancestors().find_map(ast::Fn::cast) {
41 if let Some(fn_def) = lifetime_token.ancestors().find_map(ast::Fn::cast) { 41 generate_fn_def_assist(acc, &fn_def, lifetime.lifetime_ident_token()?.text_range())
42 generate_fn_def_assist(acc, &fn_def, lifetime_token.text_range()) 42 } else if let Some(impl_def) = lifetime.syntax().ancestors().find_map(ast::Impl::cast) {
43 } else if let Some(impl_def) = lifetime_token.ancestors().find_map(ast::Impl::cast) { 43 generate_impl_def_assist(acc, &impl_def, lifetime.lifetime_ident_token()?.text_range())
44 generate_impl_def_assist(acc, &impl_def, lifetime_token.text_range())
45 } else { 44 } else {
46 None 45 None
47 } 46 }
@@ -58,7 +57,7 @@ fn generate_fn_def_assist(
58 let end_of_fn_ident = fn_def.name()?.ident_token()?.text_range().end(); 57 let end_of_fn_ident = fn_def.name()?.ident_token()?.text_range().end();
59 let self_param = 58 let self_param =
60 // use the self if it's a reference and has no explicit lifetime 59 // use the self if it's a reference and has no explicit lifetime
61 param_list.self_param().filter(|p| p.lifetime_token().is_none() && p.amp_token().is_some()); 60 param_list.self_param().filter(|p| p.lifetime().is_none() && p.amp_token().is_some());
62 // compute the location which implicitly has the same lifetime as the anonymous lifetime 61 // compute the location which implicitly has the same lifetime as the anonymous lifetime
63 let loc_needing_lifetime = if let Some(self_param) = self_param { 62 let loc_needing_lifetime = if let Some(self_param) = self_param {
64 // if we have a self reference, use that 63 // if we have a self reference, use that
@@ -68,9 +67,7 @@ fn generate_fn_def_assist(
68 let fn_params_without_lifetime: Vec<_> = param_list 67 let fn_params_without_lifetime: Vec<_> = param_list
69 .params() 68 .params()
70 .filter_map(|param| match param.ty() { 69 .filter_map(|param| match param.ty() {
71 Some(ast::Type::RefType(ascribed_type)) 70 Some(ast::Type::RefType(ascribed_type)) if ascribed_type.lifetime().is_none() => {
72 if ascribed_type.lifetime_token() == None =>
73 {
74 Some(ascribed_type.amp_token()?.text_range().end()) 71 Some(ascribed_type.amp_token()?.text_range().end())
75 } 72 }
76 _ => None, 73 _ => None,
diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs
index b9315f6c0..93869f92e 100644
--- a/crates/completion/src/completions/unqualified_path.rs
+++ b/crates/completion/src/completions/unqualified_path.rs
@@ -126,7 +126,7 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
126 let anchor = ctx.name_ref_syntax.as_ref()?; 126 let anchor = ctx.name_ref_syntax.as_ref()?;
127 let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?; 127 let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?;
128 128
129 let possible_imports = imports_locator::find_similar_imports( 129 let mut all_mod_paths = imports_locator::find_similar_imports(
130 &ctx.sema, 130 &ctx.sema,
131 ctx.krate?, 131 ctx.krate?,
132 Some(100), 132 Some(100),
@@ -144,15 +144,24 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
144 }) 144 })
145 }) 145 })
146 .filter(|(mod_path, _)| mod_path.len() > 1) 146 .filter(|(mod_path, _)| mod_path.len() > 1)
147 .filter_map(|(import_path, definition)| { 147 .collect::<Vec<_>>();
148
149 all_mod_paths.sort_by_cached_key(|(mod_path, _)| {
150 if let Some(name) = mod_path.segments.last().map(|name| name.to_string().to_lowercase()) {
151 if name.contains(&potential_import_name.to_lowercase()) {
152 return 0;
153 }
154 }
155 1
156 });
157
158 acc.add_all(all_mod_paths.into_iter().filter_map(|(import_path, definition)| {
148 render_resolution_with_import( 159 render_resolution_with_import(
149 RenderContext::new(ctx), 160 RenderContext::new(ctx),
150 ImportEdit { import_path, import_scope: import_scope.clone() }, 161 ImportEdit { import_path, import_scope: import_scope.clone() },
151 &definition, 162 &definition,
152 ) 163 )
153 }); 164 }));
154
155 acc.add_all(possible_imports);
156 Some(()) 165 Some(())
157} 166}
158 167
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index 7ffa79996..3248f6d20 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -267,7 +267,12 @@ impl ModuleDef {
267 _ => return, 267 _ => return,
268 }; 268 };
269 269
270 hir_ty::diagnostics::validate_module_item(db, id, sink) 270 let module = match self.module(db) {
271 Some(it) => it,
272 None => return,
273 };
274
275 hir_ty::diagnostics::validate_module_item(db, module.id.krate, id, sink)
271 } 276 }
272} 277}
273 278
@@ -397,9 +402,9 @@ impl Module {
397 def_map[self.id.local_id].scope.declarations().map(ModuleDef::from).collect() 402 def_map[self.id.local_id].scope.declarations().map(ModuleDef::from).collect()
398 } 403 }
399 404
400 pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<ImplDef> { 405 pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl> {
401 let def_map = db.crate_def_map(self.id.krate); 406 let def_map = db.crate_def_map(self.id.krate);
402 def_map[self.id.local_id].scope.impls().map(ImplDef::from).collect() 407 def_map[self.id.local_id].scope.impls().map(Impl::from).collect()
403 } 408 }
404 409
405 pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module { 410 pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module {
@@ -780,8 +785,9 @@ impl Function {
780 } 785 }
781 786
782 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 787 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
788 let krate = self.module(db).id.krate;
783 hir_def::diagnostics::validate_body(db.upcast(), self.id.into(), sink); 789 hir_def::diagnostics::validate_body(db.upcast(), self.id.into(), sink);
784 hir_ty::diagnostics::validate_module_item(db, self.id.into(), sink); 790 hir_ty::diagnostics::validate_module_item(db, krate, self.id.into(), sink);
785 hir_ty::diagnostics::validate_body(db, self.id.into(), sink); 791 hir_ty::diagnostics::validate_body(db, self.id.into(), sink);
786 } 792 }
787 793
@@ -970,7 +976,7 @@ impl MacroDef {
970 /// defines this macro. The reasons for this is that macros are expanded 976 /// defines this macro. The reasons for this is that macros are expanded
971 /// early, in `hir_expand`, where modules simply do not exist yet. 977 /// early, in `hir_expand`, where modules simply do not exist yet.
972 pub fn module(self, db: &dyn HirDatabase) -> Option<Module> { 978 pub fn module(self, db: &dyn HirDatabase) -> Option<Module> {
973 let krate = self.id.krate?; 979 let krate = self.id.krate;
974 let module_id = db.crate_def_map(krate).root; 980 let module_id = db.crate_def_map(krate).root;
975 Some(Module::new(Crate { id: krate }, module_id)) 981 Some(Module::new(Crate { id: krate }, module_id))
976 } 982 }
@@ -1007,7 +1013,7 @@ pub enum AssocItem {
1007} 1013}
1008pub enum AssocItemContainer { 1014pub enum AssocItemContainer {
1009 Trait(Trait), 1015 Trait(Trait),
1010 ImplDef(ImplDef), 1016 Impl(Impl),
1011} 1017}
1012pub trait AsAssocItem { 1018pub trait AsAssocItem {
1013 fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>; 1019 fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>;
@@ -1064,7 +1070,7 @@ impl AssocItem {
1064 }; 1070 };
1065 match container { 1071 match container {
1066 AssocContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()), 1072 AssocContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()),
1067 AssocContainerId::ImplId(id) => AssocItemContainer::ImplDef(id.into()), 1073 AssocContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()),
1068 AssocContainerId::ContainerId(_) => panic!("invalid AssocItem"), 1074 AssocContainerId::ContainerId(_) => panic!("invalid AssocItem"),
1069 } 1075 }
1070 } 1076 }
@@ -1086,7 +1092,7 @@ pub enum GenericDef {
1086 Adt(Adt), 1092 Adt(Adt),
1087 Trait(Trait), 1093 Trait(Trait),
1088 TypeAlias(TypeAlias), 1094 TypeAlias(TypeAlias),
1089 ImplDef(ImplDef), 1095 Impl(Impl),
1090 // enum variants cannot have generics themselves, but their parent enums 1096 // enum variants cannot have generics themselves, but their parent enums
1091 // can, and this makes some code easier to write 1097 // can, and this makes some code easier to write
1092 EnumVariant(EnumVariant), 1098 EnumVariant(EnumVariant),
@@ -1098,7 +1104,7 @@ impl_from!(
1098 Adt(Struct, Enum, Union), 1104 Adt(Struct, Enum, Union),
1099 Trait, 1105 Trait,
1100 TypeAlias, 1106 TypeAlias,
1101 ImplDef, 1107 Impl,
1102 EnumVariant, 1108 EnumVariant,
1103 Const 1109 Const
1104 for GenericDef 1110 for GenericDef
@@ -1268,30 +1274,28 @@ impl LifetimeParam {
1268 1274
1269// FIXME: rename from `ImplDef` to `Impl` 1275// FIXME: rename from `ImplDef` to `Impl`
1270#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 1276#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1271pub struct ImplDef { 1277pub struct Impl {
1272 pub(crate) id: ImplId, 1278 pub(crate) id: ImplId,
1273} 1279}
1274 1280
1275impl ImplDef { 1281impl Impl {
1276 pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<ImplDef> { 1282 pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<Impl> {
1277 let inherent = db.inherent_impls_in_crate(krate.id); 1283 let inherent = db.inherent_impls_in_crate(krate.id);
1278 let trait_ = db.trait_impls_in_crate(krate.id); 1284 let trait_ = db.trait_impls_in_crate(krate.id);
1279 1285
1280 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() 1286 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
1281 } 1287 }
1282 pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplDef> { 1288 pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<Impl> {
1283 let impls = db.trait_impls_in_crate(krate.id); 1289 let impls = db.trait_impls_in_crate(krate.id);
1284 impls.for_trait(trait_.id).map(Self::from).collect() 1290 impls.for_trait(trait_.id).map(Self::from).collect()
1285 } 1291 }
1286 1292
1293 // FIXME: the return type is wrong. This should be a hir version of
1294 // `TraitRef` (ie, resolved `TypeRef`).
1287 pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> { 1295 pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> {
1288 db.impl_data(self.id).target_trait.clone() 1296 db.impl_data(self.id).target_trait.clone()
1289 } 1297 }
1290 1298
1291 pub fn target_type(self, db: &dyn HirDatabase) -> TypeRef {
1292 db.impl_data(self.id).target_type.clone()
1293 }
1294
1295 pub fn target_ty(self, db: &dyn HirDatabase) -> Type { 1299 pub fn target_ty(self, db: &dyn HirDatabase) -> Type {
1296 let impl_data = db.impl_data(self.id); 1300 let impl_data = db.impl_data(self.id);
1297 let resolver = self.id.resolver(db.upcast()); 1301 let resolver = self.id.resolver(db.upcast());
@@ -1325,6 +1329,7 @@ impl ImplDef {
1325 let item = src.file_id.is_builtin_derive(db.upcast())?; 1329 let item = src.file_id.is_builtin_derive(db.upcast())?;
1326 let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id); 1330 let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id);
1327 1331
1332 // FIXME: handle `cfg_attr`
1328 let attr = item 1333 let attr = item
1329 .value 1334 .value
1330 .attrs() 1335 .attrs()
@@ -1904,7 +1909,7 @@ pub enum ScopeDef {
1904 ModuleDef(ModuleDef), 1909 ModuleDef(ModuleDef),
1905 MacroDef(MacroDef), 1910 MacroDef(MacroDef),
1906 GenericParam(TypeParam), 1911 GenericParam(TypeParam),
1907 ImplSelfType(ImplDef), 1912 ImplSelfType(Impl),
1908 AdtSelfType(Adt), 1913 AdtSelfType(Adt),
1909 Local(Local), 1914 Local(Local),
1910 Unknown, 1915 Unknown,
diff --git a/crates/hir/src/db.rs b/crates/hir/src/db.rs
index 8d949b264..d01e1b33d 100644
--- a/crates/hir/src/db.rs
+++ b/crates/hir/src/db.rs
@@ -6,8 +6,8 @@ pub use hir_def::db::{
6 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, ImportMapQuery, InternConstQuery, 6 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, ImportMapQuery, InternConstQuery,
7 InternDatabase, InternDatabaseStorage, InternEnumQuery, InternFunctionQuery, InternImplQuery, 7 InternDatabase, InternDatabaseStorage, InternEnumQuery, InternFunctionQuery, InternImplQuery,
8 InternStaticQuery, InternStructQuery, InternTraitQuery, InternTypeAliasQuery, InternUnionQuery, 8 InternStaticQuery, InternStructQuery, InternTraitQuery, InternTypeAliasQuery, InternUnionQuery,
9 ItemTreeQuery, LangItemQuery, ModuleLangItemsQuery, StaticDataQuery, StructDataQuery, 9 ItemTreeQuery, LangItemQuery, StaticDataQuery, StructDataQuery, TraitDataQuery,
10 TraitDataQuery, TypeAliasDataQuery, UnionDataQuery, 10 TypeAliasDataQuery, UnionDataQuery,
11}; 11};
12pub use hir_expand::db::{ 12pub use hir_expand::db::{
13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery, 13 AstDatabase, AstDatabaseStorage, AstIdMapQuery, InternEagerExpansionQuery, InternMacroQuery,
diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs
index dd3fcfe4a..8d0f84508 100644
--- a/crates/hir/src/from_id.rs
+++ b/crates/hir/src/from_id.rs
@@ -39,7 +39,7 @@ from_id![
39 (hir_def::StaticId, crate::Static), 39 (hir_def::StaticId, crate::Static),
40 (hir_def::ConstId, crate::Const), 40 (hir_def::ConstId, crate::Const),
41 (hir_def::FunctionId, crate::Function), 41 (hir_def::FunctionId, crate::Function),
42 (hir_def::ImplId, crate::ImplDef), 42 (hir_def::ImplId, crate::Impl),
43 (hir_def::TypeParamId, crate::TypeParam), 43 (hir_def::TypeParamId, crate::TypeParam),
44 (hir_def::LifetimeParamId, crate::LifetimeParam), 44 (hir_def::LifetimeParamId, crate::LifetimeParam),
45 (hir_expand::MacroDefId, crate::MacroDef) 45 (hir_expand::MacroDefId, crate::MacroDef)
@@ -146,7 +146,7 @@ impl From<GenericDef> for GenericDefId {
146 GenericDef::Adt(it) => GenericDefId::AdtId(it.into()), 146 GenericDef::Adt(it) => GenericDefId::AdtId(it.into()),
147 GenericDef::Trait(it) => GenericDefId::TraitId(it.id), 147 GenericDef::Trait(it) => GenericDefId::TraitId(it.id),
148 GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id), 148 GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id),
149 GenericDef::ImplDef(it) => GenericDefId::ImplId(it.id), 149 GenericDef::Impl(it) => GenericDefId::ImplId(it.id),
150 GenericDef::EnumVariant(it) => { 150 GenericDef::EnumVariant(it) => {
151 GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id }) 151 GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id })
152 } 152 }
@@ -162,7 +162,7 @@ impl From<GenericDefId> for GenericDef {
162 GenericDefId::AdtId(it) => GenericDef::Adt(it.into()), 162 GenericDefId::AdtId(it) => GenericDef::Adt(it.into()),
163 GenericDefId::TraitId(it) => GenericDef::Trait(it.into()), 163 GenericDefId::TraitId(it) => GenericDef::Trait(it.into()),
164 GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), 164 GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()),
165 GenericDefId::ImplId(it) => GenericDef::ImplDef(it.into()), 165 GenericDefId::ImplId(it) => GenericDef::Impl(it.into()),
166 GenericDefId::EnumVariantId(it) => { 166 GenericDefId::EnumVariantId(it) => {
167 GenericDef::EnumVariant(EnumVariant { parent: it.parent.into(), id: it.local_id }) 167 GenericDef::EnumVariant(EnumVariant { parent: it.parent.into(), id: it.local_id })
168 } 168 }
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs
index 04845037f..c5b81b252 100644
--- a/crates/hir/src/has_source.rs
+++ b/crates/hir/src/has_source.rs
@@ -10,8 +10,8 @@ use hir_expand::InFile;
10use syntax::ast; 10use syntax::ast;
11 11
12use crate::{ 12use crate::{
13 db::HirDatabase, Const, Enum, EnumVariant, Field, FieldSource, Function, ImplDef, 13 db::HirDatabase, Const, Enum, EnumVariant, Field, FieldSource, Function, Impl, LifetimeParam,
14 LifetimeParam, MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, 14 MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union,
15}; 15};
16 16
17pub trait HasSource { 17pub trait HasSource {
@@ -110,15 +110,15 @@ impl HasSource for TypeAlias {
110 } 110 }
111} 111}
112impl HasSource for MacroDef { 112impl HasSource for MacroDef {
113 type Ast = ast::MacroRules; 113 type Ast = ast::Macro;
114 fn source(self, db: &dyn HirDatabase) -> InFile<ast::MacroRules> { 114 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Macro> {
115 InFile { 115 InFile {
116 file_id: self.id.ast_id.expect("MacroDef without ast_id").file_id, 116 file_id: self.id.ast_id.expect("MacroDef without ast_id").file_id,
117 value: self.id.ast_id.expect("MacroDef without ast_id").to_node(db.upcast()), 117 value: self.id.ast_id.expect("MacroDef without ast_id").to_node(db.upcast()),
118 } 118 }
119 } 119 }
120} 120}
121impl HasSource for ImplDef { 121impl HasSource for Impl {
122 type Ast = ast::Impl; 122 type Ast = ast::Impl;
123 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Impl> { 123 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Impl> {
124 self.id.lookup(db.upcast()).source(db.upcast()) 124 self.id.lookup(db.upcast()).source(db.upcast())
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 0f399a2c6..3f4f8d8e4 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -35,7 +35,7 @@ pub use crate::{
35 code_model::{ 35 code_model::{
36 Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const, 36 Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const,
37 Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function, 37 Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function,
38 GenericDef, HasVisibility, ImplDef, LifetimeParam, Local, MacroDef, Module, ModuleDef, 38 GenericDef, HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module, ModuleDef,
39 ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, 39 ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef,
40 }, 40 },
41 has_source::HasSource, 41 has_source::HasSource,
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 5959ac4ca..83ec91f58 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -25,7 +25,7 @@ use crate::{
25 diagnostics::Diagnostic, 25 diagnostics::Diagnostic,
26 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, 26 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
27 source_analyzer::{resolve_hir_path, SourceAnalyzer}, 27 source_analyzer::{resolve_hir_path, SourceAnalyzer},
28 AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, LifetimeParam, Local, 28 AssocItem, Callable, Crate, Field, Function, HirFileId, Impl, InFile, LifetimeParam, Local,
29 MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, 29 MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam,
30 VariantDef, 30 VariantDef,
31}; 31};
@@ -38,7 +38,7 @@ pub enum PathResolution {
38 Local(Local), 38 Local(Local),
39 /// A generic parameter 39 /// A generic parameter
40 TypeParam(TypeParam), 40 TypeParam(TypeParam),
41 SelfType(ImplDef), 41 SelfType(Impl),
42 Macro(MacroDef), 42 Macro(MacroDef),
43 AssocItem(AssocItem), 43 AssocItem(AssocItem),
44} 44}
@@ -178,9 +178,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
178 self.imp.descend_node_at_offset(node, offset).find_map(N::cast) 178 self.imp.descend_node_at_offset(node, offset).find_map(N::cast)
179 } 179 }
180 180
181 // FIXME: Replace the SyntaxToken with a typed ast Node/Token 181 pub fn resolve_lifetime_param(&self, lifetime: &ast::Lifetime) -> Option<LifetimeParam> {
182 pub fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> { 182 self.imp.resolve_lifetime_param(lifetime)
183 self.imp.resolve_lifetime_param(lifetime_token)
184 } 183 }
185 184
186 pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { 185 pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
@@ -402,13 +401,9 @@ impl<'db> SemanticsImpl<'db> {
402 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) 401 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len())
403 } 402 }
404 403
405 // FIXME: Replace the SyntaxToken with a typed ast Node/Token 404 fn resolve_lifetime_param(&self, lifetime: &ast::Lifetime) -> Option<LifetimeParam> {
406 fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> { 405 let text = lifetime.text();
407 if lifetime_token.kind() != syntax::SyntaxKind::LIFETIME { 406 let lifetime_param = lifetime.syntax().ancestors().find_map(|syn| {
408 return None;
409 }
410 let lifetime_text = lifetime_token.text();
411 let lifetime_param = lifetime_token.parent().ancestors().find_map(|syn| {
412 let gpl = match_ast! { 407 let gpl = match_ast! {
413 match syn { 408 match syn {
414 ast::Fn(it) => it.generic_param_list()?, 409 ast::Fn(it) => it.generic_param_list()?,
@@ -424,7 +419,7 @@ impl<'db> SemanticsImpl<'db> {
424 } 419 }
425 }; 420 };
426 gpl.lifetime_params() 421 gpl.lifetime_params()
427 .find(|tp| tp.lifetime_token().as_ref().map(|lt| lt.text()) == Some(lifetime_text)) 422 .find(|tp| tp.lifetime().as_ref().map(|lt| lt.text()) == Some(text))
428 })?; 423 })?;
429 let src = self.find_file(lifetime_param.syntax().clone()).with_value(lifetime_param); 424 let src = self.find_file(lifetime_param.syntax().clone()).with_value(lifetime_param);
430 ToDef::to_def(self, src) 425 ToDef::to_def(self, src)
@@ -713,7 +708,7 @@ to_def_impls![
713 (crate::Enum, ast::Enum, enum_to_def), 708 (crate::Enum, ast::Enum, enum_to_def),
714 (crate::Union, ast::Union, union_to_def), 709 (crate::Union, ast::Union, union_to_def),
715 (crate::Trait, ast::Trait, trait_to_def), 710 (crate::Trait, ast::Trait, trait_to_def),
716 (crate::ImplDef, ast::Impl, impl_to_def), 711 (crate::Impl, ast::Impl, impl_to_def),
717 (crate::TypeAlias, ast::TypeAlias, type_alias_to_def), 712 (crate::TypeAlias, ast::TypeAlias, type_alias_to_def),
718 (crate::Const, ast::Const, const_to_def), 713 (crate::Const, ast::Const, const_to_def),
719 (crate::Static, ast::Static, static_to_def), 714 (crate::Static, ast::Static, static_to_def),
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index a333d7aea..3efca5baa 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -157,8 +157,8 @@ impl SourceToDefCtx<'_, '_> {
157 let file_id = src.file_id.original_file(self.db.upcast()); 157 let file_id = src.file_id.original_file(self.db.upcast());
158 let krate = self.file_to_def(file_id)?.krate; 158 let krate = self.file_to_def(file_id)?.krate;
159 let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); 159 let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value);
160 let ast_id = Some(AstId::new(src.file_id, file_ast_id)); 160 let ast_id = Some(AstId::new(src.file_id, file_ast_id.upcast()));
161 Some(MacroDefId { krate: Some(krate), ast_id, kind, local_inner: false }) 161 Some(MacroDefId { krate, ast_id, kind, local_inner: false })
162 } 162 }
163 163
164 pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> { 164 pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> {
diff --git a/crates/hir_def/src/adt.rs b/crates/hir_def/src/adt.rs
index eafa3abb6..236d6f1b7 100644
--- a/crates/hir_def/src/adt.rs
+++ b/crates/hir_def/src/adt.rs
@@ -3,6 +3,7 @@
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use arena::{map::ArenaMap, Arena}; 5use arena::{map::ArenaMap, Arena};
6use base_db::CrateId;
6use either::Either; 7use either::Either;
7use hir_expand::{ 8use hir_expand::{
8 name::{AsName, Name}, 9 name::{AsName, Name},
@@ -66,8 +67,13 @@ pub enum ReprKind {
66 Other, 67 Other,
67} 68}
68 69
69fn repr_from_value(item_tree: &ItemTree, of: AttrOwner) -> Option<ReprKind> { 70fn repr_from_value(
70 item_tree.attrs(of).by_key("repr").tt_values().find_map(parse_repr_tt) 71 db: &dyn DefDatabase,
72 krate: CrateId,
73 item_tree: &ItemTree,
74 of: AttrOwner,
75) -> Option<ReprKind> {
76 item_tree.attrs(db, krate, of).by_key("repr").tt_values().find_map(parse_repr_tt)
71} 77}
72 78
73fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> { 79fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> {
@@ -86,12 +92,13 @@ fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> {
86impl StructData { 92impl StructData {
87 pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { 93 pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> {
88 let loc = id.lookup(db); 94 let loc = id.lookup(db);
95 let krate = loc.container.module(db).krate;
89 let item_tree = db.item_tree(loc.id.file_id); 96 let item_tree = db.item_tree(loc.id.file_id);
90 let repr = repr_from_value(&item_tree, ModItem::from(loc.id.value).into()); 97 let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
91 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); 98 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone();
92 99
93 let strukt = &item_tree[loc.id.value]; 100 let strukt = &item_tree[loc.id.value];
94 let variant_data = lower_fields(&item_tree, &cfg_options, &strukt.fields, None); 101 let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &strukt.fields, None);
95 Arc::new(StructData { 102 Arc::new(StructData {
96 name: strukt.name.clone(), 103 name: strukt.name.clone(),
97 variant_data: Arc::new(variant_data), 104 variant_data: Arc::new(variant_data),
@@ -100,12 +107,13 @@ impl StructData {
100 } 107 }
101 pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> { 108 pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> {
102 let loc = id.lookup(db); 109 let loc = id.lookup(db);
110 let krate = loc.container.module(db).krate;
103 let item_tree = db.item_tree(loc.id.file_id); 111 let item_tree = db.item_tree(loc.id.file_id);
104 let repr = repr_from_value(&item_tree, ModItem::from(loc.id.value).into()); 112 let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
105 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); 113 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone();
106 114
107 let union = &item_tree[loc.id.value]; 115 let union = &item_tree[loc.id.value];
108 let variant_data = lower_fields(&item_tree, &cfg_options, &union.fields, None); 116 let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &union.fields, None);
109 117
110 Arc::new(StructData { 118 Arc::new(StructData {
111 name: union.name.clone(), 119 name: union.name.clone(),
@@ -118,16 +126,23 @@ impl StructData {
118impl EnumData { 126impl EnumData {
119 pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> { 127 pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> {
120 let loc = e.lookup(db); 128 let loc = e.lookup(db);
129 let krate = loc.container.module(db).krate;
121 let item_tree = db.item_tree(loc.id.file_id); 130 let item_tree = db.item_tree(loc.id.file_id);
122 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); 131 let cfg_options = db.crate_graph()[krate].cfg_options.clone();
123 132
124 let enum_ = &item_tree[loc.id.value]; 133 let enum_ = &item_tree[loc.id.value];
125 let mut variants = Arena::new(); 134 let mut variants = Arena::new();
126 for var_id in enum_.variants.clone() { 135 for var_id in enum_.variants.clone() {
127 if item_tree.attrs(var_id.into()).is_cfg_enabled(&cfg_options) { 136 if item_tree.attrs(db, krate, var_id.into()).is_cfg_enabled(&cfg_options) {
128 let var = &item_tree[var_id]; 137 let var = &item_tree[var_id];
129 let var_data = 138 let var_data = lower_fields(
130 lower_fields(&item_tree, &cfg_options, &var.fields, Some(enum_.visibility)); 139 db,
140 krate,
141 &item_tree,
142 &cfg_options,
143 &var.fields,
144 Some(enum_.visibility),
145 );
131 146
132 variants.alloc(EnumVariantData { 147 variants.alloc(EnumVariantData {
133 name: var.name.clone(), 148 name: var.name.clone(),
@@ -170,7 +185,7 @@ fn lower_enum(
170 .variant_list() 185 .variant_list()
171 .into_iter() 186 .into_iter()
172 .flat_map(|it| it.variants()) 187 .flat_map(|it| it.variants())
173 .filter(|var| expander.is_cfg_enabled(var)); 188 .filter(|var| expander.is_cfg_enabled(db, var));
174 for var in variants { 189 for var in variants {
175 trace.alloc( 190 trace.alloc(
176 || var.clone(), 191 || var.clone(),
@@ -262,7 +277,7 @@ fn lower_struct(
262 match &ast.value { 277 match &ast.value {
263 ast::StructKind::Tuple(fl) => { 278 ast::StructKind::Tuple(fl) => {
264 for (i, fd) in fl.fields().enumerate() { 279 for (i, fd) in fl.fields().enumerate() {
265 if !expander.is_cfg_enabled(&fd) { 280 if !expander.is_cfg_enabled(db, &fd) {
266 continue; 281 continue;
267 } 282 }
268 283
@@ -279,7 +294,7 @@ fn lower_struct(
279 } 294 }
280 ast::StructKind::Record(fl) => { 295 ast::StructKind::Record(fl) => {
281 for fd in fl.fields() { 296 for fd in fl.fields() {
282 if !expander.is_cfg_enabled(&fd) { 297 if !expander.is_cfg_enabled(db, &fd) {
283 continue; 298 continue;
284 } 299 }
285 300
@@ -299,6 +314,8 @@ fn lower_struct(
299} 314}
300 315
301fn lower_fields( 316fn lower_fields(
317 db: &dyn DefDatabase,
318 krate: CrateId,
302 item_tree: &ItemTree, 319 item_tree: &ItemTree,
303 cfg_options: &CfgOptions, 320 cfg_options: &CfgOptions,
304 fields: &Fields, 321 fields: &Fields,
@@ -308,7 +325,7 @@ fn lower_fields(
308 Fields::Record(flds) => { 325 Fields::Record(flds) => {
309 let mut arena = Arena::new(); 326 let mut arena = Arena::new();
310 for field_id in flds.clone() { 327 for field_id in flds.clone() {
311 if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) { 328 if item_tree.attrs(db, krate, field_id.into()).is_cfg_enabled(cfg_options) {
312 arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility)); 329 arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility));
313 } 330 }
314 } 331 }
@@ -317,7 +334,7 @@ fn lower_fields(
317 Fields::Tuple(flds) => { 334 Fields::Tuple(flds) => {
318 let mut arena = Arena::new(); 335 let mut arena = Arena::new();
319 for field_id in flds.clone() { 336 for field_id in flds.clone() {
320 if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) { 337 if item_tree.attrs(db, krate, field_id.into()).is_cfg_enabled(cfg_options) {
321 arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility)); 338 arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility));
322 } 339 }
323 } 340 }
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index c64b78445..9cd0b72aa 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -2,6 +2,7 @@
2 2
3use std::{ops, sync::Arc}; 3use std::{ops, sync::Arc};
4 4
5use base_db::CrateId;
5use cfg::{CfgExpr, CfgOptions}; 6use cfg::{CfgExpr, CfgOptions};
6use either::Either; 7use either::Either;
7use hir_expand::{hygiene::Hygiene, AstId, InFile}; 8use hir_expand::{hygiene::Hygiene, AstId, InFile};
@@ -38,12 +39,16 @@ impl From<Documentation> for String {
38 } 39 }
39} 40}
40 41
42/// Syntactical attributes, without filtering of `cfg_attr`s.
41#[derive(Default, Debug, Clone, PartialEq, Eq)] 43#[derive(Default, Debug, Clone, PartialEq, Eq)]
42pub struct Attrs { 44pub struct RawAttrs {
43 entries: Option<Arc<[Attr]>>, 45 entries: Option<Arc<[Attr]>>,
44} 46}
45 47
46impl ops::Deref for Attrs { 48#[derive(Default, Debug, Clone, PartialEq, Eq)]
49pub struct Attrs(RawAttrs);
50
51impl ops::Deref for RawAttrs {
47 type Target = [Attr]; 52 type Target = [Attr];
48 53
49 fn deref(&self) -> &[Attr] { 54 fn deref(&self) -> &[Attr] {
@@ -54,19 +59,88 @@ impl ops::Deref for Attrs {
54 } 59 }
55} 60}
56 61
62impl ops::Deref for Attrs {
63 type Target = [Attr];
64
65 fn deref(&self) -> &[Attr] {
66 match &self.0.entries {
67 Some(it) => &*it,
68 None => &[],
69 }
70 }
71}
72
73impl RawAttrs {
74 pub const EMPTY: Self = Self { entries: None };
75
76 pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Self {
77 let (inner_attrs, inner_docs) = inner_attributes(owner.syntax())
78 .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs))));
79
80 let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none());
81 let attrs = outer_attrs
82 .chain(inner_attrs.into_iter().flatten())
83 .map(|attr| (attr.syntax().text_range().start(), Attr::from_src(attr, hygiene)));
84
85 let outer_docs =
86 ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer);
87 let docs = outer_docs.chain(inner_docs.into_iter().flatten()).map(|docs_text| {
88 (
89 docs_text.syntax().text_range().start(),
90 docs_text.doc_comment().map(|doc| Attr {
91 input: Some(AttrInput::Literal(SmolStr::new(doc))),
92 path: ModPath::from(hir_expand::name!(doc)),
93 }),
94 )
95 });
96 // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved
97 let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect();
98 let entries = if attrs.is_empty() {
99 // Avoid heap allocation
100 None
101 } else {
102 Some(attrs.into_iter().flat_map(|(_, attr)| attr).collect())
103 };
104 Self { entries }
105 }
106
107 fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Self {
108 let hygiene = Hygiene::new(db.upcast(), owner.file_id);
109 Self::new(owner.value, &hygiene)
110 }
111
112 pub(crate) fn merge(&self, other: Self) -> Self {
113 match (&self.entries, &other.entries) {
114 (None, None) => Self::EMPTY,
115 (Some(entries), None) | (None, Some(entries)) => {
116 Self { entries: Some(entries.clone()) }
117 }
118 (Some(a), Some(b)) => {
119 Self { entries: Some(a.iter().chain(b.iter()).cloned().collect()) }
120 }
121 }
122 }
123
124 /// Processes `cfg_attr`s, returning the resulting semantic `Attrs`.
125 pub(crate) fn filter(self, _db: &dyn DefDatabase, _krate: CrateId) -> Attrs {
126 // FIXME actually implement this
127 Attrs(self)
128 }
129}
130
57impl Attrs { 131impl Attrs {
58 pub const EMPTY: Attrs = Attrs { entries: None }; 132 pub const EMPTY: Self = Self(RawAttrs::EMPTY);
59 133
60 pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs { 134 pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs {
61 match def { 135 let raw_attrs = match def {
62 AttrDefId::ModuleId(module) => { 136 AttrDefId::ModuleId(module) => {
63 let def_map = db.crate_def_map(module.krate); 137 let def_map = db.crate_def_map(module.krate);
64 let mod_data = &def_map[module.local_id]; 138 let mod_data = &def_map[module.local_id];
65 match mod_data.declaration_source(db) { 139 match mod_data.declaration_source(db) {
66 Some(it) => { 140 Some(it) => {
67 Attrs::from_attrs_owner(db, it.as_ref().map(|it| it as &dyn AttrsOwner)) 141 RawAttrs::from_attrs_owner(db, it.as_ref().map(|it| it as &dyn AttrsOwner))
68 } 142 }
69 None => Attrs::from_attrs_owner( 143 None => RawAttrs::from_attrs_owner(
70 db, 144 db,
71 mod_data.definition_source(db).as_ref().map(|src| match src { 145 mod_data.definition_source(db).as_ref().map(|src| match src {
72 ModuleSource::SourceFile(file) => file as &dyn AttrsOwner, 146 ModuleSource::SourceFile(file) => file as &dyn AttrsOwner,
@@ -78,14 +152,14 @@ impl Attrs {
78 AttrDefId::FieldId(it) => { 152 AttrDefId::FieldId(it) => {
79 let src = it.parent.child_source(db); 153 let src = it.parent.child_source(db);
80 match &src.value[it.local_id] { 154 match &src.value[it.local_id] {
81 Either::Left(_tuple) => Attrs::default(), 155 Either::Left(_tuple) => RawAttrs::default(),
82 Either::Right(record) => Attrs::from_attrs_owner(db, src.with_value(record)), 156 Either::Right(record) => RawAttrs::from_attrs_owner(db, src.with_value(record)),
83 } 157 }
84 } 158 }
85 AttrDefId::EnumVariantId(var_id) => { 159 AttrDefId::EnumVariantId(var_id) => {
86 let src = var_id.parent.child_source(db); 160 let src = var_id.parent.child_source(db);
87 let src = src.as_ref().map(|it| &it[var_id.local_id]); 161 let src = src.as_ref().map(|it| &it[var_id.local_id]);
88 Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) 162 RawAttrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner))
89 } 163 }
90 AttrDefId::AdtId(it) => match it { 164 AttrDefId::AdtId(it) => match it {
91 AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db), 165 AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db),
@@ -101,53 +175,19 @@ impl Attrs {
101 AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db), 175 AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db),
102 AttrDefId::FunctionId(it) => attrs_from_item_tree(it.lookup(db).id, db), 176 AttrDefId::FunctionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
103 AttrDefId::TypeAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db), 177 AttrDefId::TypeAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db),
104 }
105 }
106
107 pub fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Attrs {
108 let hygiene = Hygiene::new(db.upcast(), owner.file_id);
109 Attrs::new(owner.value, &hygiene)
110 }
111
112 pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs {
113 let (inner_attrs, inner_docs) = inner_attributes(owner.syntax())
114 .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs))));
115
116 let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none());
117 let attrs = outer_attrs
118 .chain(inner_attrs.into_iter().flatten())
119 .map(|attr| (attr.syntax().text_range().start(), Attr::from_src(attr, hygiene)));
120
121 let outer_docs =
122 ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer);
123 let docs = outer_docs.chain(inner_docs.into_iter().flatten()).map(|docs_text| {
124 (
125 docs_text.syntax().text_range().start(),
126 docs_text.doc_comment().map(|doc| Attr {
127 input: Some(AttrInput::Literal(SmolStr::new(doc))),
128 path: ModPath::from(hir_expand::name!(doc)),
129 }),
130 )
131 });
132 // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved
133 let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect();
134 let entries = if attrs.is_empty() {
135 // Avoid heap allocation
136 None
137 } else {
138 Some(attrs.into_iter().flat_map(|(_, attr)| attr).collect())
139 }; 178 };
140 Attrs { entries } 179
180 raw_attrs.filter(db, def.krate(db))
141 } 181 }
142 182
143 pub fn merge(&self, other: Attrs) -> Attrs { 183 pub fn merge(&self, other: Attrs) -> Attrs {
144 match (&self.entries, &other.entries) { 184 match (&self.0.entries, &other.0.entries) {
145 (None, None) => Attrs { entries: None }, 185 (None, None) => Attrs::EMPTY,
146 (Some(entries), None) | (None, Some(entries)) => { 186 (Some(entries), None) | (None, Some(entries)) => {
147 Attrs { entries: Some(entries.clone()) } 187 Attrs(RawAttrs { entries: Some(entries.clone()) })
148 } 188 }
149 (Some(a), Some(b)) => { 189 (Some(a), Some(b)) => {
150 Attrs { entries: Some(a.iter().chain(b.iter()).cloned().collect()) } 190 Attrs(RawAttrs { entries: Some(a.iter().chain(b.iter()).cloned().collect()) })
151 } 191 }
152 } 192 }
153 } 193 }
@@ -291,16 +331,16 @@ impl<'a> AttrQuery<'a> {
291 } 331 }
292} 332}
293 333
294fn attrs_from_ast<N>(src: AstId<N>, db: &dyn DefDatabase) -> Attrs 334fn attrs_from_ast<N>(src: AstId<N>, db: &dyn DefDatabase) -> RawAttrs
295where 335where
296 N: ast::AttrsOwner, 336 N: ast::AttrsOwner,
297{ 337{
298 let src = InFile::new(src.file_id, src.to_node(db.upcast())); 338 let src = InFile::new(src.file_id, src.to_node(db.upcast()));
299 Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) 339 RawAttrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
300} 340}
301 341
302fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> Attrs { 342fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> RawAttrs {
303 let tree = db.item_tree(id.file_id); 343 let tree = db.item_tree(id.file_id);
304 let mod_item = N::id_to_mod_item(id.value); 344 let mod_item = N::id_to_mod_item(id.value);
305 tree.attrs(mod_item.into()).clone() 345 tree.raw_attrs(mod_item.into()).clone()
306} 346}
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs
index c5d6f5fb0..998b82601 100644
--- a/crates/hir_def/src/body.rs
+++ b/crates/hir_def/src/body.rs
@@ -24,7 +24,7 @@ use test_utils::mark;
24pub(crate) use lower::LowerCtx; 24pub(crate) use lower::LowerCtx;
25 25
26use crate::{ 26use crate::{
27 attr::Attrs, 27 attr::{Attrs, RawAttrs},
28 db::DefDatabase, 28 db::DefDatabase,
29 expr::{Expr, ExprId, Pat, PatId}, 29 expr::{Expr, ExprId, Pat, PatId},
30 item_scope::BuiltinShadowMode, 30 item_scope::BuiltinShadowMode,
@@ -40,6 +40,7 @@ use crate::{
40pub(crate) struct CfgExpander { 40pub(crate) struct CfgExpander {
41 cfg_options: CfgOptions, 41 cfg_options: CfgOptions,
42 hygiene: Hygiene, 42 hygiene: Hygiene,
43 krate: CrateId,
43} 44}
44 45
45pub(crate) struct Expander { 46pub(crate) struct Expander {
@@ -65,15 +66,15 @@ impl CfgExpander {
65 ) -> CfgExpander { 66 ) -> CfgExpander {
66 let hygiene = Hygiene::new(db.upcast(), current_file_id); 67 let hygiene = Hygiene::new(db.upcast(), current_file_id);
67 let cfg_options = db.crate_graph()[krate].cfg_options.clone(); 68 let cfg_options = db.crate_graph()[krate].cfg_options.clone();
68 CfgExpander { cfg_options, hygiene } 69 CfgExpander { cfg_options, hygiene, krate }
69 } 70 }
70 71
71 pub(crate) fn parse_attrs(&self, owner: &dyn ast::AttrsOwner) -> Attrs { 72 pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> Attrs {
72 Attrs::new(owner, &self.hygiene) 73 RawAttrs::new(owner, &self.hygiene).filter(db, self.krate)
73 } 74 }
74 75
75 pub(crate) fn is_cfg_enabled(&self, owner: &dyn ast::AttrsOwner) -> bool { 76 pub(crate) fn is_cfg_enabled(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> bool {
76 let attrs = self.parse_attrs(owner); 77 let attrs = self.parse_attrs(db, owner);
77 attrs.is_cfg_enabled(&self.cfg_options) 78 attrs.is_cfg_enabled(&self.cfg_options)
78 } 79 }
79} 80}
@@ -189,8 +190,8 @@ impl Expander {
189 InFile { file_id: self.current_file_id, value } 190 InFile { file_id: self.current_file_id, value }
190 } 191 }
191 192
192 pub(crate) fn parse_attrs(&self, owner: &dyn ast::AttrsOwner) -> Attrs { 193 pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> Attrs {
193 self.cfg_expander.parse_attrs(owner) 194 self.cfg_expander.parse_attrs(db, owner)
194 } 195 }
195 196
196 pub(crate) fn cfg_options(&self) -> &CfgOptions { 197 pub(crate) fn cfg_options(&self) -> &CfgOptions {
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index bdba4c33e..0f404be1b 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -233,8 +233,7 @@ impl ExprCollector<'_> {
233 let res = self.collect_block(block); 233 let res = self.collect_block(block);
234 match &mut self.body.exprs[res] { 234 match &mut self.body.exprs[res] {
235 Expr::Block { label: block_label, .. } => { 235 Expr::Block { label: block_label, .. } => {
236 *block_label = 236 *block_label = label.lifetime().map(|t| Name::new_lifetime(&t))
237 label.lifetime_token().map(|t| Name::new_lifetime(&t))
238 } 237 }
239 _ => unreachable!(), 238 _ => unreachable!(),
240 } 239 }
@@ -254,10 +253,7 @@ impl ExprCollector<'_> {
254 self.alloc_expr( 253 self.alloc_expr(
255 Expr::Loop { 254 Expr::Loop {
256 body, 255 body,
257 label: e 256 label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)),
258 .label()
259 .and_then(|l| l.lifetime_token())
260 .map(|l| Name::new_lifetime(&l)),
261 }, 257 },
262 syntax_ptr, 258 syntax_ptr,
263 ) 259 )
@@ -288,7 +284,7 @@ impl ExprCollector<'_> {
288 body: match_expr, 284 body: match_expr,
289 label: e 285 label: e
290 .label() 286 .label()
291 .and_then(|l| l.lifetime_token()) 287 .and_then(|l| l.lifetime())
292 .map(|l| Name::new_lifetime(&l)), 288 .map(|l| Name::new_lifetime(&l)),
293 }, 289 },
294 syntax_ptr, 290 syntax_ptr,
@@ -301,10 +297,7 @@ impl ExprCollector<'_> {
301 Expr::While { 297 Expr::While {
302 condition, 298 condition,
303 body, 299 body,
304 label: e 300 label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)),
305 .label()
306 .and_then(|l| l.lifetime_token())
307 .map(|l| Name::new_lifetime(&l)),
308 }, 301 },
309 syntax_ptr, 302 syntax_ptr,
310 ) 303 )
@@ -318,10 +311,7 @@ impl ExprCollector<'_> {
318 iterable, 311 iterable,
319 pat, 312 pat,
320 body, 313 body,
321 label: e 314 label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)),
322 .label()
323 .and_then(|l| l.lifetime_token())
324 .map(|l| Name::new_lifetime(&l)),
325 }, 315 },
326 syntax_ptr, 316 syntax_ptr,
327 ) 317 )
@@ -380,13 +370,13 @@ impl ExprCollector<'_> {
380 self.alloc_expr(path, syntax_ptr) 370 self.alloc_expr(path, syntax_ptr)
381 } 371 }
382 ast::Expr::ContinueExpr(e) => self.alloc_expr( 372 ast::Expr::ContinueExpr(e) => self.alloc_expr(
383 Expr::Continue { label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) }, 373 Expr::Continue { label: e.lifetime().map(|l| Name::new_lifetime(&l)) },
384 syntax_ptr, 374 syntax_ptr,
385 ), 375 ),
386 ast::Expr::BreakExpr(e) => { 376 ast::Expr::BreakExpr(e) => {
387 let expr = e.expr().map(|e| self.collect_expr(e)); 377 let expr = e.expr().map(|e| self.collect_expr(e));
388 self.alloc_expr( 378 self.alloc_expr(
389 Expr::Break { expr, label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) }, 379 Expr::Break { expr, label: e.lifetime().map(|l| Name::new_lifetime(&l)) },
390 syntax_ptr, 380 syntax_ptr,
391 ) 381 )
392 } 382 }
@@ -772,7 +762,10 @@ impl ExprCollector<'_> {
772 | ast::Item::Module(_) 762 | ast::Item::Module(_)
773 | ast::Item::MacroCall(_) => return None, 763 | ast::Item::MacroCall(_) => return None,
774 ast::Item::MacroRules(def) => { 764 ast::Item::MacroRules(def) => {
775 return Some(Either::Right(def)); 765 return Some(Either::Right(ast::Macro::from(def)));
766 }
767 ast::Item::MacroDef(def) => {
768 return Some(Either::Right(ast::Macro::from(def)));
776 } 769 }
777 }; 770 };
778 771
@@ -800,7 +793,7 @@ impl ExprCollector<'_> {
800 } 793 }
801 Either::Right(e) => { 794 Either::Right(e) => {
802 let mac = MacroDefId { 795 let mac = MacroDefId {
803 krate: Some(self.expander.module.krate), 796 krate: self.expander.module.krate,
804 ast_id: Some(self.expander.ast_id(&e)), 797 ast_id: Some(self.expander.ast_id(&e)),
805 kind: MacroDefKind::Declarative, 798 kind: MacroDefKind::Declarative,
806 local_inner: false, 799 local_inner: false,
@@ -970,7 +963,7 @@ impl ExprCollector<'_> {
970 /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when 963 /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when
971 /// not. 964 /// not.
972 fn check_cfg(&mut self, owner: &dyn ast::AttrsOwner) -> Option<()> { 965 fn check_cfg(&mut self, owner: &dyn ast::AttrsOwner) -> Option<()> {
973 match self.expander.parse_attrs(owner).cfg() { 966 match self.expander.parse_attrs(self.db, owner).cfg() {
974 Some(cfg) => { 967 Some(cfg) => {
975 if self.expander.cfg_options().check(&cfg) != Some(false) { 968 if self.expander.cfg_options().check(&cfg) != Some(false) {
976 return Some(()); 969 return Some(());
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index dd3a906af..e7b7724f7 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -35,6 +35,7 @@ pub struct FunctionData {
35impl FunctionData { 35impl FunctionData {
36 pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> { 36 pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> {
37 let loc = func.lookup(db); 37 let loc = func.lookup(db);
38 let krate = loc.container.module(db).krate;
38 let item_tree = db.item_tree(loc.id.file_id); 39 let item_tree = db.item_tree(loc.id.file_id);
39 let func = &item_tree[loc.id.value]; 40 let func = &item_tree[loc.id.value];
40 41
@@ -42,7 +43,7 @@ impl FunctionData {
42 name: func.name.clone(), 43 name: func.name.clone(),
43 params: func.params.to_vec(), 44 params: func.params.to_vec(),
44 ret_type: func.ret_type.clone(), 45 ret_type: func.ret_type.clone(),
45 attrs: item_tree.attrs(ModItem::from(loc.id.value).into()).clone(), 46 attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()).clone(),
46 has_self_param: func.has_self_param, 47 has_self_param: func.has_self_param,
47 has_body: func.has_body, 48 has_body: func.has_body,
48 is_unsafe: func.is_unsafe, 49 is_unsafe: func.is_unsafe,
@@ -233,7 +234,7 @@ fn collect_items(
233 match item { 234 match item {
234 AssocItem::Function(id) => { 235 AssocItem::Function(id) => {
235 let item = &item_tree[id]; 236 let item = &item_tree[id];
236 let attrs = item_tree.attrs(ModItem::from(id).into()); 237 let attrs = item_tree.attrs(db, module.krate, ModItem::from(id).into());
237 if !attrs.is_cfg_enabled(&cfg_options) { 238 if !attrs.is_cfg_enabled(&cfg_options) {
238 continue; 239 continue;
239 } 240 }
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs
index 7f250da33..d1a459066 100644
--- a/crates/hir_def/src/db.rs
+++ b/crates/hir_def/src/db.rs
@@ -16,8 +16,8 @@ use crate::{
16 lang_item::{LangItemTarget, LangItems}, 16 lang_item::{LangItemTarget, LangItems},
17 nameres::CrateDefMap, 17 nameres::CrateDefMap,
18 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, 18 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
19 GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, 19 GenericDefId, ImplId, ImplLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc,
20 TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, 20 TypeAliasId, TypeAliasLoc, UnionId, UnionLoc,
21}; 21};
22 22
23#[salsa::query_group(InternDatabaseStorage)] 23#[salsa::query_group(InternDatabaseStorage)]
@@ -95,9 +95,6 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
95 #[salsa::invoke(Attrs::attrs_query)] 95 #[salsa::invoke(Attrs::attrs_query)]
96 fn attrs(&self, def: AttrDefId) -> Attrs; 96 fn attrs(&self, def: AttrDefId) -> Attrs;
97 97
98 #[salsa::invoke(LangItems::module_lang_items_query)]
99 fn module_lang_items(&self, module: ModuleId) -> Option<Arc<LangItems>>;
100
101 #[salsa::invoke(LangItems::crate_lang_items_query)] 98 #[salsa::invoke(LangItems::crate_lang_items_query)]
102 fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>; 99 fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>;
103 100
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs
index 924046435..41134d23b 100644
--- a/crates/hir_def/src/generics.rs
+++ b/crates/hir_def/src/generics.rs
@@ -260,9 +260,8 @@ impl GenericParams {
260 self.fill_bounds(&lower_ctx, &type_param, Either::Left(type_ref)); 260 self.fill_bounds(&lower_ctx, &type_param, Either::Left(type_ref));
261 } 261 }
262 for lifetime_param in params.lifetime_params() { 262 for lifetime_param in params.lifetime_params() {
263 let name = lifetime_param 263 let name =
264 .lifetime_token() 264 lifetime_param.lifetime().map_or_else(Name::missing, |lt| Name::new_lifetime(&lt));
265 .map_or_else(Name::missing, |tok| Name::new_lifetime(&tok));
266 let param = LifetimeParamData { name: name.clone() }; 265 let param = LifetimeParamData { name: name.clone() };
267 let param_id = self.lifetimes.alloc(param); 266 let param_id = self.lifetimes.alloc(param);
268 sm.lifetime_params.insert(param_id, lifetime_param.clone()); 267 sm.lifetime_params.insert(param_id, lifetime_param.clone());
@@ -275,8 +274,8 @@ impl GenericParams {
275 for pred in where_clause.predicates() { 274 for pred in where_clause.predicates() {
276 let target = if let Some(type_ref) = pred.ty() { 275 let target = if let Some(type_ref) = pred.ty() {
277 Either::Left(TypeRef::from_ast(lower_ctx, type_ref)) 276 Either::Left(TypeRef::from_ast(lower_ctx, type_ref))
278 } else if let Some(lifetime_tok) = pred.lifetime_token() { 277 } else if let Some(lifetime) = pred.lifetime() {
279 Either::Right(LifetimeRef::from_token(lifetime_tok)) 278 Either::Right(LifetimeRef::new(&lifetime))
280 } else { 279 } else {
281 continue; 280 continue;
282 }; 281 };
diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs
index a8b3fe844..62ab3b2bd 100644
--- a/crates/hir_def/src/item_scope.rs
+++ b/crates/hir_def/src/item_scope.rs
@@ -363,7 +363,7 @@ impl ItemInNs {
363 ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db).krate, 363 ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db).krate,
364 ModuleDefId::BuiltinType(_) => return None, 364 ModuleDefId::BuiltinType(_) => return None,
365 }, 365 },
366 ItemInNs::Macros(id) => return id.krate, 366 ItemInNs::Macros(id) => return Some(id.krate),
367 }) 367 })
368 } 368 }
369} 369}
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 1c9babf37..5eb7cae7f 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -13,6 +13,7 @@ use std::{
13 13
14use arena::{Arena, Idx, RawId}; 14use arena::{Arena, Idx, RawId};
15use ast::{AstNode, AttrsOwner, NameOwner, StructKind}; 15use ast::{AstNode, AttrsOwner, NameOwner, StructKind};
16use base_db::CrateId;
16use either::Either; 17use either::Either;
17use hir_expand::{ 18use hir_expand::{
18 ast_id_map::FileAstId, 19 ast_id_map::FileAstId,
@@ -26,7 +27,7 @@ use syntax::{ast, match_ast};
26use test_utils::mark; 27use test_utils::mark;
27 28
28use crate::{ 29use crate::{
29 attr::Attrs, 30 attr::{Attrs, RawAttrs},
30 db::DefDatabase, 31 db::DefDatabase,
31 generics::GenericParams, 32 generics::GenericParams,
32 path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind}, 33 path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind},
@@ -67,7 +68,7 @@ impl GenericParamsId {
67#[derive(Debug, Eq, PartialEq)] 68#[derive(Debug, Eq, PartialEq)]
68pub struct ItemTree { 69pub struct ItemTree {
69 top_level: SmallVec<[ModItem; 1]>, 70 top_level: SmallVec<[ModItem; 1]>,
70 attrs: FxHashMap<AttrOwner, Attrs>, 71 attrs: FxHashMap<AttrOwner, RawAttrs>,
71 inner_items: FxHashMap<FileAstId<ast::Item>, SmallVec<[ModItem; 1]>>, 72 inner_items: FxHashMap<FileAstId<ast::Item>, SmallVec<[ModItem; 1]>>,
72 73
73 data: Option<Box<ItemTreeData>>, 74 data: Option<Box<ItemTreeData>>,
@@ -88,7 +89,7 @@ impl ItemTree {
88 let mut item_tree = match_ast! { 89 let mut item_tree = match_ast! {
89 match syntax { 90 match syntax {
90 ast::SourceFile(file) => { 91 ast::SourceFile(file) => {
91 top_attrs = Some(Attrs::new(&file, &hygiene)); 92 top_attrs = Some(RawAttrs::new(&file, &hygiene));
92 ctx.lower_module_items(&file) 93 ctx.lower_module_items(&file)
93 }, 94 },
94 ast::MacroItems(items) => { 95 ast::MacroItems(items) => {
@@ -143,6 +144,7 @@ impl ItemTree {
143 mods, 144 mods,
144 macro_calls, 145 macro_calls,
145 macro_rules, 146 macro_rules,
147 macro_defs,
146 exprs, 148 exprs,
147 vis, 149 vis,
148 generics, 150 generics,
@@ -164,6 +166,7 @@ impl ItemTree {
164 mods.shrink_to_fit(); 166 mods.shrink_to_fit();
165 macro_calls.shrink_to_fit(); 167 macro_calls.shrink_to_fit();
166 macro_rules.shrink_to_fit(); 168 macro_rules.shrink_to_fit();
169 macro_defs.shrink_to_fit();
167 exprs.shrink_to_fit(); 170 exprs.shrink_to_fit();
168 171
169 vis.arena.shrink_to_fit(); 172 vis.arena.shrink_to_fit();
@@ -178,12 +181,16 @@ impl ItemTree {
178 } 181 }
179 182
180 /// Returns the inner attributes of the source file. 183 /// Returns the inner attributes of the source file.
181 pub fn top_level_attrs(&self) -> &Attrs { 184 pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: CrateId) -> Attrs {
182 self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&Attrs::EMPTY) 185 self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&RawAttrs::EMPTY).clone().filter(db, krate)
183 } 186 }
184 187
185 pub fn attrs(&self, of: AttrOwner) -> &Attrs { 188 pub(crate) fn raw_attrs(&self, of: AttrOwner) -> &RawAttrs {
186 self.attrs.get(&of).unwrap_or(&Attrs::EMPTY) 189 self.attrs.get(&of).unwrap_or(&RawAttrs::EMPTY)
190 }
191
192 pub fn attrs(&self, db: &dyn DefDatabase, krate: CrateId, of: AttrOwner) -> Attrs {
193 self.raw_attrs(of).clone().filter(db, krate)
187 } 194 }
188 195
189 /// Returns the lowered inner items that `ast` corresponds to. 196 /// Returns the lowered inner items that `ast` corresponds to.
@@ -283,6 +290,7 @@ struct ItemTreeData {
283 mods: Arena<Mod>, 290 mods: Arena<Mod>,
284 macro_calls: Arena<MacroCall>, 291 macro_calls: Arena<MacroCall>,
285 macro_rules: Arena<MacroRules>, 292 macro_rules: Arena<MacroRules>,
293 macro_defs: Arena<MacroDef>,
286 exprs: Arena<Expr>, 294 exprs: Arena<Expr>,
287 295
288 vis: ItemVisibilities, 296 vis: ItemVisibilities,
@@ -431,6 +439,7 @@ mod_items! {
431 Mod in mods -> ast::Module, 439 Mod in mods -> ast::Module,
432 MacroCall in macro_calls -> ast::MacroCall, 440 MacroCall in macro_calls -> ast::MacroCall,
433 MacroRules in macro_rules -> ast::MacroRules, 441 MacroRules in macro_rules -> ast::MacroRules,
442 MacroDef in macro_defs -> ast::MacroDef,
434} 443}
435 444
436macro_rules! impl_index { 445macro_rules! impl_index {
@@ -640,17 +649,19 @@ pub struct MacroCall {
640 649
641#[derive(Debug, Clone, Eq, PartialEq)] 650#[derive(Debug, Clone, Eq, PartialEq)]
642pub struct MacroRules { 651pub struct MacroRules {
643 /// For `macro_rules!` declarations, this is the name of the declared macro. 652 /// The name of the declared macro.
644 pub name: Name, 653 pub name: Name,
645 /// Has `#[macro_export]`.
646 pub is_export: bool,
647 /// Has `#[macro_export(local_inner_macros)]`.
648 pub is_local_inner: bool,
649 /// Has `#[rustc_builtin_macro]`.
650 pub is_builtin: bool,
651 pub ast_id: FileAstId<ast::MacroRules>, 654 pub ast_id: FileAstId<ast::MacroRules>,
652} 655}
653 656
657/// "Macros 2.0" macro definition.
658#[derive(Debug, Clone, Eq, PartialEq)]
659pub struct MacroDef {
660 pub name: Name,
661 pub visibility: RawVisibilityId,
662 pub ast_id: FileAstId<ast::MacroDef>,
663}
664
654// NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array 665// NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array
655// lengths, but we don't do much with them yet. 666// lengths, but we don't do much with them yet.
656#[derive(Debug, Clone, Eq, PartialEq)] 667#[derive(Debug, Clone, Eq, PartialEq)]
@@ -680,7 +691,8 @@ impl ModItem {
680 | ModItem::Trait(_) 691 | ModItem::Trait(_)
681 | ModItem::Impl(_) 692 | ModItem::Impl(_)
682 | ModItem::Mod(_) 693 | ModItem::Mod(_)
683 | ModItem::MacroRules(_) => None, 694 | ModItem::MacroRules(_)
695 | ModItem::MacroDef(_) => None,
684 ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)), 696 ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)),
685 ModItem::Const(konst) => Some(AssocItem::Const(*konst)), 697 ModItem::Const(konst) => Some(AssocItem::Const(*konst)),
686 ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)), 698 ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)),
@@ -708,6 +720,7 @@ impl ModItem {
708 ModItem::Mod(it) => tree[it.index].ast_id().upcast(), 720 ModItem::Mod(it) => tree[it.index].ast_id().upcast(),
709 ModItem::MacroCall(it) => tree[it.index].ast_id().upcast(), 721 ModItem::MacroCall(it) => tree[it.index].ast_id().upcast(),
710 ModItem::MacroRules(it) => tree[it.index].ast_id().upcast(), 722 ModItem::MacroRules(it) => tree[it.index].ast_id().upcast(),
723 ModItem::MacroDef(it) => tree[it.index].ast_id().upcast(),
711 } 724 }
712 } 725 }
713} 726}
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index b39d7fb7a..c8f090c22 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -10,7 +10,6 @@ use syntax::{
10}; 10};
11 11
12use crate::{ 12use crate::{
13 attr::Attrs,
14 generics::{GenericParams, TypeParamData, TypeParamProvenance}, 13 generics::{GenericParams, TypeParamData, TypeParamProvenance},
15 type_ref::LifetimeRef, 14 type_ref::LifetimeRef,
16}; 15};
@@ -101,10 +100,11 @@ impl Ctx {
101 | ast::Item::ExternCrate(_) 100 | ast::Item::ExternCrate(_)
102 | ast::Item::Use(_) 101 | ast::Item::Use(_)
103 | ast::Item::MacroCall(_) 102 | ast::Item::MacroCall(_)
104 | ast::Item::MacroRules(_) => {} 103 | ast::Item::MacroRules(_)
104 | ast::Item::MacroDef(_) => {}
105 }; 105 };
106 106
107 let attrs = Attrs::new(item, &self.hygiene); 107 let attrs = RawAttrs::new(item, &self.hygiene);
108 let items = match item { 108 let items = match item {
109 ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into), 109 ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into),
110 ast::Item::Union(ast) => self.lower_union(ast).map(Into::into), 110 ast::Item::Union(ast) => self.lower_union(ast).map(Into::into),
@@ -122,6 +122,7 @@ impl Ctx {
122 ast::Item::ExternCrate(ast) => self.lower_extern_crate(ast).map(Into::into), 122 ast::Item::ExternCrate(ast) => self.lower_extern_crate(ast).map(Into::into),
123 ast::Item::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into), 123 ast::Item::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into),
124 ast::Item::MacroRules(ast) => self.lower_macro_rules(ast).map(Into::into), 124 ast::Item::MacroRules(ast) => self.lower_macro_rules(ast).map(Into::into),
125 ast::Item::MacroDef(ast) => self.lower_macro_def(ast).map(Into::into),
125 ast::Item::ExternBlock(ast) => { 126 ast::Item::ExternBlock(ast) => {
126 Some(ModItems(self.lower_extern_block(ast).into_iter().collect::<SmallVec<_>>())) 127 Some(ModItems(self.lower_extern_block(ast).into_iter().collect::<SmallVec<_>>()))
127 } 128 }
@@ -136,7 +137,7 @@ impl Ctx {
136 items 137 items
137 } 138 }
138 139
139 fn add_attrs(&mut self, item: AttrOwner, attrs: Attrs) { 140 fn add_attrs(&mut self, item: AttrOwner, attrs: RawAttrs) {
140 match self.tree.attrs.entry(item) { 141 match self.tree.attrs.entry(item) {
141 Entry::Occupied(mut entry) => { 142 Entry::Occupied(mut entry) => {
142 *entry.get_mut() = entry.get().merge(attrs); 143 *entry.get_mut() = entry.get().merge(attrs);
@@ -203,7 +204,7 @@ impl Ctx {
203 for field in fields.fields() { 204 for field in fields.fields() {
204 if let Some(data) = self.lower_record_field(&field) { 205 if let Some(data) = self.lower_record_field(&field) {
205 let idx = self.data().fields.alloc(data); 206 let idx = self.data().fields.alloc(data);
206 self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene)); 207 self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene));
207 } 208 }
208 } 209 }
209 let end = self.next_field_idx(); 210 let end = self.next_field_idx();
@@ -223,7 +224,7 @@ impl Ctx {
223 for (i, field) in fields.fields().enumerate() { 224 for (i, field) in fields.fields().enumerate() {
224 let data = self.lower_tuple_field(i, &field); 225 let data = self.lower_tuple_field(i, &field);
225 let idx = self.data().fields.alloc(data); 226 let idx = self.data().fields.alloc(data);
226 self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene)); 227 self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene));
227 } 228 }
228 let end = self.next_field_idx(); 229 let end = self.next_field_idx();
229 IdRange::new(start..end) 230 IdRange::new(start..end)
@@ -268,7 +269,7 @@ impl Ctx {
268 for variant in variants.variants() { 269 for variant in variants.variants() {
269 if let Some(data) = self.lower_variant(&variant) { 270 if let Some(data) = self.lower_variant(&variant) {
270 let idx = self.data().variants.alloc(data); 271 let idx = self.data().variants.alloc(data);
271 self.add_attrs(idx.into(), Attrs::new(&variant, &self.hygiene)); 272 self.add_attrs(idx.into(), RawAttrs::new(&variant, &self.hygiene));
272 } 273 }
273 } 274 }
274 let end = self.next_variant_idx(); 275 let end = self.next_variant_idx();
@@ -298,12 +299,12 @@ impl Ctx {
298 ast::SelfParamKind::Owned => self_type, 299 ast::SelfParamKind::Owned => self_type,
299 ast::SelfParamKind::Ref => TypeRef::Reference( 300 ast::SelfParamKind::Ref => TypeRef::Reference(
300 Box::new(self_type), 301 Box::new(self_type),
301 self_param.lifetime_token().map(LifetimeRef::from_token), 302 self_param.lifetime().as_ref().map(LifetimeRef::new),
302 Mutability::Shared, 303 Mutability::Shared,
303 ), 304 ),
304 ast::SelfParamKind::MutRef => TypeRef::Reference( 305 ast::SelfParamKind::MutRef => TypeRef::Reference(
305 Box::new(self_type), 306 Box::new(self_type),
306 self_param.lifetime_token().map(LifetimeRef::from_token), 307 self_param.lifetime().as_ref().map(LifetimeRef::new),
307 Mutability::Mut, 308 Mutability::Mut,
308 ), 309 ),
309 } 310 }
@@ -436,7 +437,7 @@ impl Ctx {
436 self.with_inherited_visibility(visibility, |this| { 437 self.with_inherited_visibility(visibility, |this| {
437 list.assoc_items() 438 list.assoc_items()
438 .filter_map(|item| { 439 .filter_map(|item| {
439 let attrs = Attrs::new(&item, &this.hygiene); 440 let attrs = RawAttrs::new(&item, &this.hygiene);
440 this.collect_inner_items(item.syntax()); 441 this.collect_inner_items(item.syntax());
441 this.lower_assoc_item(&item).map(|item| { 442 this.lower_assoc_item(&item).map(|item| {
442 this.add_attrs(ModItem::from(item).into(), attrs); 443 this.add_attrs(ModItem::from(item).into(), attrs);
@@ -473,7 +474,7 @@ impl Ctx {
473 .filter_map(|item| { 474 .filter_map(|item| {
474 self.collect_inner_items(item.syntax()); 475 self.collect_inner_items(item.syntax());
475 let assoc = self.lower_assoc_item(&item)?; 476 let assoc = self.lower_assoc_item(&item)?;
476 let attrs = Attrs::new(&item, &self.hygiene); 477 let attrs = RawAttrs::new(&item, &self.hygiene);
477 self.add_attrs(ModItem::from(assoc).into(), attrs); 478 self.add_attrs(ModItem::from(assoc).into(), attrs);
478 Some(assoc) 479 Some(assoc)
479 }) 480 })
@@ -537,28 +538,20 @@ impl Ctx {
537 538
538 fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> { 539 fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> {
539 let name = m.name().map(|it| it.as_name())?; 540 let name = m.name().map(|it| it.as_name())?;
540 let attrs = Attrs::new(m, &self.hygiene);
541
542 let ast_id = self.source_ast_id_map.ast_id(m); 541 let ast_id = self.source_ast_id_map.ast_id(m);
543 542
544 // FIXME: cfg_attr 543 let res = MacroRules { name, ast_id };
545 let export_attr = attrs.by_key("macro_export"); 544 Some(id(self.data().macro_rules.alloc(res)))
545 }
546 546
547 let is_export = export_attr.exists(); 547 fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<FileItemTreeId<MacroDef>> {
548 let is_local_inner = if is_export { 548 let name = m.name().map(|it| it.as_name())?;
549 export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it {
550 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
551 ident.text.contains("local_inner_macros")
552 }
553 _ => false,
554 })
555 } else {
556 false
557 };
558 549
559 let is_builtin = attrs.by_key("rustc_builtin_macro").exists(); 550 let ast_id = self.source_ast_id_map.ast_id(m);
560 let res = MacroRules { name, is_export, is_builtin, is_local_inner, ast_id }; 551 let visibility = self.lower_visibility(m);
561 Some(id(self.data().macro_rules.alloc(res))) 552
553 let res = MacroDef { name, ast_id, visibility };
554 Some(id(self.data().macro_defs.alloc(res)))
562 } 555 }
563 556
564 fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> Vec<ModItem> { 557 fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> Vec<ModItem> {
@@ -566,7 +559,7 @@ impl Ctx {
566 list.extern_items() 559 list.extern_items()
567 .filter_map(|item| { 560 .filter_map(|item| {
568 self.collect_inner_items(item.syntax()); 561 self.collect_inner_items(item.syntax());
569 let attrs = Attrs::new(&item, &self.hygiene); 562 let attrs = RawAttrs::new(&item, &self.hygiene);
570 let id: ModItem = match item { 563 let id: ModItem = match item {
571 ast::ExternItem::Fn(ast) => { 564 ast::ExternItem::Fn(ast) => {
572 let func_id = self.lower_function(&ast)?; 565 let func_id = self.lower_function(&ast)?;
diff --git a/crates/hir_def/src/lang_item.rs b/crates/hir_def/src/lang_item.rs
index 063eadccb..30188b740 100644
--- a/crates/hir_def/src/lang_item.rs
+++ b/crates/hir_def/src/lang_item.rs
@@ -8,8 +8,8 @@ use rustc_hash::FxHashMap;
8use syntax::SmolStr; 8use syntax::SmolStr;
9 9
10use crate::{ 10use crate::{
11 db::DefDatabase, AdtId, AttrDefId, CrateId, EnumId, FunctionId, ImplId, ModuleDefId, ModuleId, 11 db::DefDatabase, AdtId, AttrDefId, CrateId, EnumId, FunctionId, ImplId, ModuleDefId, StaticId,
12 StaticId, StructId, TraitId, 12 StructId, TraitId,
13}; 13};
14 14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -84,27 +84,34 @@ impl LangItems {
84 84
85 let crate_def_map = db.crate_def_map(krate); 85 let crate_def_map = db.crate_def_map(krate);
86 86
87 crate_def_map 87 for (_, module_data) in crate_def_map.modules.iter() {
88 .modules 88 for impl_def in module_data.scope.impls() {
89 .iter() 89 lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDefId)
90 .filter_map(|(local_id, _)| db.module_lang_items(ModuleId { krate, local_id })) 90 }
91 .for_each(|it| lang_items.items.extend(it.items.iter().map(|(k, v)| (k.clone(), *v))));
92
93 Arc::new(lang_items)
94 }
95 91
96 pub(crate) fn module_lang_items_query( 92 for def in module_data.scope.declarations() {
97 db: &dyn DefDatabase, 93 match def {
98 module: ModuleId, 94 ModuleDefId::TraitId(trait_) => {
99 ) -> Option<Arc<LangItems>> { 95 lang_items.collect_lang_item(db, trait_, LangItemTarget::TraitId)
100 let _p = profile::span("module_lang_items_query"); 96 }
101 let mut lang_items = LangItems::default(); 97 ModuleDefId::AdtId(AdtId::EnumId(e)) => {
102 lang_items.collect_lang_items(db, module); 98 lang_items.collect_lang_item(db, e, LangItemTarget::EnumId)
103 if lang_items.items.is_empty() { 99 }
104 None 100 ModuleDefId::AdtId(AdtId::StructId(s)) => {
105 } else { 101 lang_items.collect_lang_item(db, s, LangItemTarget::StructId)
106 Some(Arc::new(lang_items)) 102 }
103 ModuleDefId::FunctionId(f) => {
104 lang_items.collect_lang_item(db, f, LangItemTarget::FunctionId)
105 }
106 ModuleDefId::StaticId(s) => {
107 lang_items.collect_lang_item(db, s, LangItemTarget::StaticId)
108 }
109 _ => {}
110 }
111 }
107 } 112 }
113
114 Arc::new(lang_items)
108 } 115 }
109 116
110 /// Salsa query. Look for a lang item, starting from the specified crate and recursively 117 /// Salsa query. Look for a lang item, starting from the specified crate and recursively
@@ -126,34 +133,6 @@ impl LangItems {
126 .find_map(|dep| db.lang_item(dep.crate_id, item.clone())) 133 .find_map(|dep| db.lang_item(dep.crate_id, item.clone()))
127 } 134 }
128 135
129 fn collect_lang_items(&mut self, db: &dyn DefDatabase, module: ModuleId) {
130 // Look for impl targets
131 let def_map = db.crate_def_map(module.krate);
132 let module_data = &def_map[module.local_id];
133 for impl_def in module_data.scope.impls() {
134 self.collect_lang_item(db, impl_def, LangItemTarget::ImplDefId)
135 }
136
137 for def in module_data.scope.declarations() {
138 match def {
139 ModuleDefId::TraitId(trait_) => {
140 self.collect_lang_item(db, trait_, LangItemTarget::TraitId)
141 }
142 ModuleDefId::AdtId(AdtId::EnumId(e)) => {
143 self.collect_lang_item(db, e, LangItemTarget::EnumId)
144 }
145 ModuleDefId::AdtId(AdtId::StructId(s)) => {
146 self.collect_lang_item(db, s, LangItemTarget::StructId)
147 }
148 ModuleDefId::FunctionId(f) => {
149 self.collect_lang_item(db, f, LangItemTarget::FunctionId)
150 }
151 ModuleDefId::StaticId(s) => self.collect_lang_item(db, s, LangItemTarget::StaticId),
152 _ => {}
153 }
154 }
155 }
156
157 fn collect_lang_item<T>( 136 fn collect_lang_item<T>(
158 &mut self, 137 &mut self,
159 db: &dyn DefDatabase, 138 db: &dyn DefDatabase,
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index 7e2199a9c..ba09a9126 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -425,6 +425,16 @@ impl HasModule for AdtId {
425 } 425 }
426} 426}
427 427
428impl HasModule for VariantId {
429 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
430 match self {
431 VariantId::EnumVariantId(it) => it.parent.lookup(db).container.module(db),
432 VariantId::StructId(it) => it.lookup(db).container.module(db),
433 VariantId::UnionId(it) => it.lookup(db).container.module(db),
434 }
435 }
436}
437
428impl HasModule for DefWithBodyId { 438impl HasModule for DefWithBodyId {
429 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { 439 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
430 match self { 440 match self {
@@ -465,6 +475,26 @@ impl HasModule for StaticLoc {
465 } 475 }
466} 476}
467 477
478impl AttrDefId {
479 pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId {
480 match self {
481 AttrDefId::ModuleId(it) => it.krate,
482 AttrDefId::FieldId(it) => it.parent.module(db).krate,
483 AttrDefId::AdtId(it) => it.module(db).krate,
484 AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate,
485 AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db).krate,
486 AttrDefId::StaticId(it) => it.lookup(db).module(db).krate,
487 AttrDefId::ConstId(it) => it.lookup(db).module(db).krate,
488 AttrDefId::TraitId(it) => it.lookup(db).container.module(db).krate,
489 AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate,
490 AttrDefId::ImplId(it) => it.lookup(db).container.module(db).krate,
491 // FIXME: `MacroDefId` should store the defining module, then this can implement
492 // `HasModule`
493 AttrDefId::MacroDefId(it) => it.krate,
494 }
495 }
496}
497
468/// A helper trait for converting to MacroCallId 498/// A helper trait for converting to MacroCallId
469pub trait AsMacroCall { 499pub trait AsMacroCall {
470 fn as_call_id( 500 fn as_call_id(
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 85cc342c4..b114a6fe4 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -26,7 +26,8 @@ use crate::{
26 db::DefDatabase, 26 db::DefDatabase,
27 item_scope::{ImportType, PerNsGlobImports}, 27 item_scope::{ImportType, PerNsGlobImports},
28 item_tree::{ 28 item_tree::{
29 self, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, StructDefKind, 29 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind,
30 StructDefKind,
30 }, 31 },
31 nameres::{ 32 nameres::{
32 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 33 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
@@ -220,17 +221,20 @@ impl DefCollector<'_> {
220 let item_tree = self.db.item_tree(file_id.into()); 221 let item_tree = self.db.item_tree(file_id.into());
221 let module_id = self.def_map.root; 222 let module_id = self.def_map.root;
222 self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; 223 self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id };
223 let mut root_collector = ModCollector { 224 if item_tree
224 def_collector: &mut *self, 225 .top_level_attrs(self.db, self.def_map.krate)
225 macro_depth: 0, 226 .cfg()
226 module_id, 227 .map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false))
227 file_id: file_id.into(),
228 item_tree: &item_tree,
229 mod_dir: ModDir::root(),
230 };
231 if item_tree.top_level_attrs().cfg().map_or(true, |cfg| root_collector.is_cfg_enabled(&cfg))
232 { 228 {
233 root_collector.collect(item_tree.top_level_items()); 229 ModCollector {
230 def_collector: &mut *self,
231 macro_depth: 0,
232 module_id,
233 file_id: file_id.into(),
234 item_tree: &item_tree,
235 mod_dir: ModDir::root(),
236 }
237 .collect(item_tree.top_level_items());
234 } 238 }
235 239
236 // main name resolution fixed-point loop. 240 // main name resolution fixed-point loop.
@@ -309,13 +313,13 @@ impl DefCollector<'_> {
309 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) { 313 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) {
310 Some((_, expander)) => MacroDefId { 314 Some((_, expander)) => MacroDefId {
311 ast_id: None, 315 ast_id: None,
312 krate: Some(self.def_map.krate), 316 krate: self.def_map.krate,
313 kind: MacroDefKind::ProcMacro(*expander), 317 kind: MacroDefKind::ProcMacro(*expander),
314 local_inner: false, 318 local_inner: false,
315 }, 319 },
316 None => MacroDefId { 320 None => MacroDefId {
317 ast_id: None, 321 ast_id: None,
318 krate: Some(self.def_map.krate), 322 krate: self.def_map.krate,
319 kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate)), 323 kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate)),
320 local_inner: false, 324 local_inner: false,
321 }, 325 },
@@ -784,14 +788,6 @@ impl DefCollector<'_> {
784 directive: &DeriveDirective, 788 directive: &DeriveDirective,
785 path: &ModPath, 789 path: &ModPath,
786 ) -> Option<MacroDefId> { 790 ) -> Option<MacroDefId> {
787 if let Some(name) = path.as_ident() {
788 // FIXME this should actually be handled with the normal name
789 // resolution; the std lib defines built-in stubs for the derives,
790 // but these are new-style `macro`s, which we don't support yet
791 if let Some(def_id) = find_builtin_derive(name) {
792 return Some(def_id);
793 }
794 }
795 let resolved_res = self.def_map.resolve_path_fp_with_macro( 791 let resolved_res = self.def_map.resolve_path_fp_with_macro(
796 self.db, 792 self.db,
797 ResolveMode::Other, 793 ResolveMode::Other,
@@ -912,6 +908,8 @@ struct ModCollector<'a, 'b> {
912 908
913impl ModCollector<'_, '_> { 909impl ModCollector<'_, '_> {
914 fn collect(&mut self, items: &[ModItem]) { 910 fn collect(&mut self, items: &[ModItem]) {
911 let krate = self.def_collector.def_map.krate;
912
915 // Note: don't assert that inserted value is fresh: it's simply not true 913 // Note: don't assert that inserted value is fresh: it's simply not true
916 // for macros. 914 // for macros.
917 self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone()); 915 self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone());
@@ -928,7 +926,7 @@ impl ModCollector<'_, '_> {
928 // `#[macro_use] extern crate` is hoisted to imports macros before collecting 926 // `#[macro_use] extern crate` is hoisted to imports macros before collecting
929 // any other items. 927 // any other items.
930 for item in items { 928 for item in items {
931 let attrs = self.item_tree.attrs((*item).into()); 929 let attrs = self.item_tree.attrs(self.def_collector.db, krate, (*item).into());
932 if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) { 930 if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) {
933 if let ModItem::ExternCrate(id) = item { 931 if let ModItem::ExternCrate(id) = item {
934 let import = self.item_tree[*id].clone(); 932 let import = self.item_tree[*id].clone();
@@ -940,7 +938,7 @@ impl ModCollector<'_, '_> {
940 } 938 }
941 939
942 for &item in items { 940 for &item in items {
943 let attrs = self.item_tree.attrs(item.into()); 941 let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into());
944 if let Some(cfg) = attrs.cfg() { 942 if let Some(cfg) = attrs.cfg() {
945 if !self.is_cfg_enabled(&cfg) { 943 if !self.is_cfg_enabled(&cfg) {
946 self.emit_unconfigured_diagnostic(item, &cfg); 944 self.emit_unconfigured_diagnostic(item, &cfg);
@@ -953,7 +951,7 @@ impl ModCollector<'_, '_> {
953 951
954 let mut def = None; 952 let mut def = None;
955 match item { 953 match item {
956 ModItem::Mod(m) => self.collect_module(&self.item_tree[m], attrs), 954 ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs),
957 ModItem::Import(import_id) => { 955 ModItem::Import(import_id) => {
958 self.def_collector.unresolved_imports.push(ImportDirective { 956 self.def_collector.unresolved_imports.push(ImportDirective {
959 module_id: self.module_id, 957 module_id: self.module_id,
@@ -975,7 +973,41 @@ impl ModCollector<'_, '_> {
975 }) 973 })
976 } 974 }
977 ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]), 975 ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]),
978 ModItem::MacroRules(mac) => self.collect_macro_rules(&self.item_tree[mac]), 976 ModItem::MacroRules(id) => self.collect_macro_rules(id),
977 ModItem::MacroDef(id) => {
978 let mac = &self.item_tree[id];
979 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
980
981 // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it
982 // to define builtin macros, so we support at least that part.
983 let attrs = self.item_tree.attrs(
984 self.def_collector.db,
985 krate,
986 ModItem::from(id).into(),
987 );
988 if attrs.by_key("rustc_builtin_macro").exists() {
989 let krate = self.def_collector.def_map.krate;
990 let macro_id = find_builtin_macro(&mac.name, krate, ast_id)
991 .or_else(|| find_builtin_derive(&mac.name, krate, ast_id));
992 if let Some(macro_id) = macro_id {
993 let vis = self
994 .def_collector
995 .def_map
996 .resolve_visibility(
997 self.def_collector.db,
998 self.module_id,
999 &self.item_tree[mac.visibility],
1000 )
1001 .unwrap_or(Visibility::Public);
1002 self.def_collector.update(
1003 self.module_id,
1004 &[(Some(mac.name.clone()), PerNs::macros(macro_id, vis))],
1005 vis,
1006 ImportType::Named,
1007 );
1008 }
1009 }
1010 }
979 ModItem::Impl(imp) => { 1011 ModItem::Impl(imp) => {
980 let module = ModuleId { 1012 let module = ModuleId {
981 krate: self.def_collector.def_map.krate, 1013 krate: self.def_collector.def_map.krate,
@@ -989,7 +1021,7 @@ impl ModCollector<'_, '_> {
989 ModItem::Function(id) => { 1021 ModItem::Function(id) => {
990 let func = &self.item_tree[id]; 1022 let func = &self.item_tree[id];
991 1023
992 self.collect_proc_macro_def(&func.name, attrs); 1024 self.collect_proc_macro_def(&func.name, &attrs);
993 1025
994 def = Some(DefData { 1026 def = Some(DefData {
995 id: FunctionLoc { 1027 id: FunctionLoc {
@@ -1009,7 +1041,7 @@ impl ModCollector<'_, '_> {
1009 // FIXME: check attrs to see if this is an attribute macro invocation; 1041 // FIXME: check attrs to see if this is an attribute macro invocation;
1010 // in which case we don't add the invocation, just a single attribute 1042 // in which case we don't add the invocation, just a single attribute
1011 // macro invocation 1043 // macro invocation
1012 self.collect_derives(attrs, it.ast_id.upcast()); 1044 self.collect_derives(&attrs, it.ast_id.upcast());
1013 1045
1014 def = Some(DefData { 1046 def = Some(DefData {
1015 id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) } 1047 id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) }
@@ -1026,7 +1058,7 @@ impl ModCollector<'_, '_> {
1026 // FIXME: check attrs to see if this is an attribute macro invocation; 1058 // FIXME: check attrs to see if this is an attribute macro invocation;
1027 // in which case we don't add the invocation, just a single attribute 1059 // in which case we don't add the invocation, just a single attribute
1028 // macro invocation 1060 // macro invocation
1029 self.collect_derives(attrs, it.ast_id.upcast()); 1061 self.collect_derives(&attrs, it.ast_id.upcast());
1030 1062
1031 def = Some(DefData { 1063 def = Some(DefData {
1032 id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) } 1064 id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) }
@@ -1043,7 +1075,7 @@ impl ModCollector<'_, '_> {
1043 // FIXME: check attrs to see if this is an attribute macro invocation; 1075 // FIXME: check attrs to see if this is an attribute macro invocation;
1044 // in which case we don't add the invocation, just a single attribute 1076 // in which case we don't add the invocation, just a single attribute
1045 // macro invocation 1077 // macro invocation
1046 self.collect_derives(attrs, it.ast_id.upcast()); 1078 self.collect_derives(&attrs, it.ast_id.upcast());
1047 1079
1048 def = Some(DefData { 1080 def = Some(DefData {
1049 id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) } 1081 id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) }
@@ -1279,18 +1311,35 @@ impl ModCollector<'_, '_> {
1279 self.def_collector.resolve_proc_macro(&macro_name); 1311 self.def_collector.resolve_proc_macro(&macro_name);
1280 } 1312 }
1281 1313
1282 fn collect_macro_rules(&mut self, mac: &MacroRules) { 1314 fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) {
1283 let ast_id = InFile::new(self.file_id, mac.ast_id); 1315 let krate = self.def_collector.def_map.krate;
1316 let mac = &self.item_tree[id];
1317 let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
1318 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
1319
1320 let export_attr = attrs.by_key("macro_export");
1321
1322 let is_export = export_attr.exists();
1323 let is_local_inner = if is_export {
1324 export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it {
1325 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
1326 ident.text.contains("local_inner_macros")
1327 }
1328 _ => false,
1329 })
1330 } else {
1331 false
1332 };
1284 1333
1285 // Case 1: builtin macros 1334 // Case 1: builtin macros
1286 if mac.is_builtin { 1335 if attrs.by_key("rustc_builtin_macro").exists() {
1287 let krate = self.def_collector.def_map.krate; 1336 let krate = self.def_collector.def_map.krate;
1288 if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) { 1337 if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) {
1289 self.def_collector.define_macro( 1338 self.def_collector.define_macro(
1290 self.module_id, 1339 self.module_id,
1291 mac.name.clone(), 1340 mac.name.clone(),
1292 macro_id, 1341 macro_id,
1293 mac.is_export, 1342 is_export,
1294 ); 1343 );
1295 return; 1344 return;
1296 } 1345 }
@@ -1299,11 +1348,11 @@ impl ModCollector<'_, '_> {
1299 // Case 2: normal `macro_rules!` macro 1348 // Case 2: normal `macro_rules!` macro
1300 let macro_id = MacroDefId { 1349 let macro_id = MacroDefId {
1301 ast_id: Some(ast_id), 1350 ast_id: Some(ast_id),
1302 krate: Some(self.def_collector.def_map.krate), 1351 krate: self.def_collector.def_map.krate,
1303 kind: MacroDefKind::Declarative, 1352 kind: MacroDefKind::Declarative,
1304 local_inner: mac.is_local_inner, 1353 local_inner: is_local_inner,
1305 }; 1354 };
1306 self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, mac.is_export); 1355 self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, is_export);
1307 } 1356 }
1308 1357
1309 fn collect_macro_call(&mut self, mac: &MacroCall) { 1358 fn collect_macro_call(&mut self, mac: &MacroCall) {
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs
index 305fca0f9..6fe2ee78a 100644
--- a/crates/hir_def/src/nameres/tests/macros.rs
+++ b/crates/hir_def/src/nameres/tests/macros.rs
@@ -633,15 +633,44 @@ pub struct bar;
633fn expand_derive() { 633fn expand_derive() {
634 let map = compute_crate_def_map( 634 let map = compute_crate_def_map(
635 " 635 "
636 //- /main.rs 636 //- /main.rs crate:main deps:core
637 use core::*;
638
637 #[derive(Copy, Clone)] 639 #[derive(Copy, Clone)]
638 struct Foo; 640 struct Foo;
641
642 //- /core.rs crate:core
643 #[rustc_builtin_macro]
644 pub macro Copy {}
645
646 #[rustc_builtin_macro]
647 pub macro Clone {}
639 ", 648 ",
640 ); 649 );
641 assert_eq!(map.modules[map.root].scope.impls().len(), 2); 650 assert_eq!(map.modules[map.root].scope.impls().len(), 2);
642} 651}
643 652
644#[test] 653#[test]
654fn resolve_builtin_derive() {
655 check(
656 r#"
657//- /main.rs crate:main deps:core
658use core::*;
659
660//- /core.rs crate:core
661#[rustc_builtin_macro]
662pub macro Clone {}
663
664pub trait Clone {}
665"#,
666 expect![[r#"
667 crate
668 Clone: t m
669 "#]],
670 );
671}
672
673#[test]
645fn macro_expansion_overflow() { 674fn macro_expansion_overflow() {
646 mark::check!(macro_expansion_overflow); 675 mark::check!(macro_expansion_overflow);
647 check( 676 check(
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs
index 609925012..8a01e6eea 100644
--- a/crates/hir_def/src/path/lower.rs
+++ b/crates/hir_def/src/path/lower.rs
@@ -169,8 +169,8 @@ pub(super) fn lower_generic_args(
169 } 169 }
170 } 170 }
171 ast::GenericArg::LifetimeArg(lifetime_arg) => { 171 ast::GenericArg::LifetimeArg(lifetime_arg) => {
172 if let Some(lifetime) = lifetime_arg.lifetime_token() { 172 if let Some(lifetime) = lifetime_arg.lifetime() {
173 let lifetime_ref = LifetimeRef::from_token(lifetime); 173 let lifetime_ref = LifetimeRef::new(&lifetime);
174 args.push(GenericArg::Lifetime(lifetime_ref)) 174 args.push(GenericArg::Lifetime(lifetime_ref))
175 } 175 }
176 } 176 }
diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs
index 347ceabb9..ae93d0d10 100644
--- a/crates/hir_def/src/type_ref.rs
+++ b/crates/hir_def/src/type_ref.rs
@@ -1,7 +1,7 @@
1//! HIR for references to types. Paths in these are not yet resolved. They can 1//! HIR for references to types. Paths in these are not yet resolved. They can
2//! be directly created from an ast::TypeRef, without further queries. 2//! be directly created from an ast::TypeRef, without further queries.
3use hir_expand::name::Name; 3use hir_expand::name::Name;
4use syntax::{ast, SyntaxToken}; 4use syntax::ast;
5 5
6use crate::{body::LowerCtx, path::Path}; 6use crate::{body::LowerCtx, path::Path};
7 7
@@ -80,8 +80,8 @@ impl LifetimeRef {
80 LifetimeRef { name } 80 LifetimeRef { name }
81 } 81 }
82 82
83 pub(crate) fn from_token(token: SyntaxToken) -> Self { 83 pub(crate) fn new(lifetime: &ast::Lifetime) -> Self {
84 LifetimeRef { name: Name::new_lifetime(&token) } 84 LifetimeRef { name: Name::new_lifetime(lifetime) }
85 } 85 }
86 86
87 pub fn missing() -> LifetimeRef { 87 pub fn missing() -> LifetimeRef {
@@ -127,7 +127,7 @@ impl TypeRef {
127 } 127 }
128 ast::Type::RefType(inner) => { 128 ast::Type::RefType(inner) => {
129 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty()); 129 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty());
130 let lifetime = inner.lifetime_token().map(|t| LifetimeRef::from_token(t)); 130 let lifetime = inner.lifetime().map(|lt| LifetimeRef::new(&lt));
131 let mutability = Mutability::from_mutable(inner.mut_token().is_some()); 131 let mutability = Mutability::from_mutable(inner.mut_token().is_some());
132 TypeRef::Reference(Box::new(inner_ty), lifetime, mutability) 132 TypeRef::Reference(Box::new(inner_ty), lifetime, mutability)
133 } 133 }
@@ -259,7 +259,7 @@ impl TypeBound {
259 } 259 }
260 ast::TypeBoundKind::ForType(_) => TypeBound::Error, // FIXME ForType 260 ast::TypeBoundKind::ForType(_) => TypeBound::Error, // FIXME ForType
261 ast::TypeBoundKind::Lifetime(lifetime) => { 261 ast::TypeBoundKind::Lifetime(lifetime) => {
262 TypeBound::Lifetime(LifetimeRef::from_token(lifetime)) 262 TypeBound::Lifetime(LifetimeRef::new(&lifetime))
263 } 263 }
264 } 264 }
265 } 265 }
diff --git a/crates/hir_expand/src/builtin_derive.rs b/crates/hir_expand/src/builtin_derive.rs
index 988a60d56..ad378762a 100644
--- a/crates/hir_expand/src/builtin_derive.rs
+++ b/crates/hir_expand/src/builtin_derive.rs
@@ -8,7 +8,7 @@ use syntax::{
8 match_ast, 8 match_ast,
9}; 9};
10 10
11use crate::{db::AstDatabase, name, quote, LazyMacroId, MacroDefId, MacroDefKind}; 11use crate::{db::AstDatabase, name, quote, AstId, CrateId, LazyMacroId, MacroDefId, MacroDefKind};
12 12
13macro_rules! register_builtin { 13macro_rules! register_builtin {
14 ( $($trait:ident => $expand:ident),* ) => { 14 ( $($trait:ident => $expand:ident),* ) => {
@@ -29,16 +29,15 @@ macro_rules! register_builtin {
29 }; 29 };
30 expander(db, id, tt) 30 expander(db, id, tt)
31 } 31 }
32 }
33
34 pub fn find_builtin_derive(ident: &name::Name) -> Option<MacroDefId> {
35 let kind = match ident {
36 $( id if id == &name::name![$trait] => BuiltinDeriveExpander::$trait, )*
37 _ => return None,
38 };
39 32
40 Some(MacroDefId { krate: None, ast_id: None, kind: MacroDefKind::BuiltInDerive(kind), local_inner: false }) 33 fn find_by_name(name: &name::Name) -> Option<Self> {
34 match name {
35 $( id if id == &name::name![$trait] => Some(BuiltinDeriveExpander::$trait), )*
36 _ => None,
37 }
38 }
41 } 39 }
40
42 }; 41 };
43} 42}
44 43
@@ -54,6 +53,20 @@ register_builtin! {
54 PartialEq => partial_eq_expand 53 PartialEq => partial_eq_expand
55} 54}
56 55
56pub fn find_builtin_derive(
57 ident: &name::Name,
58 krate: CrateId,
59 ast_id: AstId<ast::Macro>,
60) -> Option<MacroDefId> {
61 let expander = BuiltinDeriveExpander::find_by_name(ident)?;
62 Some(MacroDefId {
63 krate,
64 ast_id: Some(ast_id),
65 kind: MacroDefKind::BuiltInDerive(expander),
66 local_inner: false,
67 })
68}
69
57struct BasicAdtInfo { 70struct BasicAdtInfo {
58 name: tt::Ident, 71 name: tt::Ident,
59 type_params: usize, 72 type_params: usize,
@@ -261,7 +274,7 @@ mod tests {
261 use super::*; 274 use super::*;
262 275
263 fn expand_builtin_derive(s: &str, name: Name) -> String { 276 fn expand_builtin_derive(s: &str, name: Name) -> String {
264 let def = find_builtin_derive(&name).unwrap(); 277 let expander = BuiltinDeriveExpander::find_by_name(&name).unwrap();
265 let fixture = format!( 278 let fixture = format!(
266 r#"//- /main.rs crate:main deps:core 279 r#"//- /main.rs crate:main deps:core
267<|> 280<|>
@@ -283,7 +296,12 @@ mod tests {
283 let attr_id = AstId::new(file_id.into(), ast_id_map.ast_id(&items[0])); 296 let attr_id = AstId::new(file_id.into(), ast_id_map.ast_id(&items[0]));
284 297
285 let loc = MacroCallLoc { 298 let loc = MacroCallLoc {
286 def, 299 def: MacroDefId {
300 krate: CrateId(0),
301 ast_id: None,
302 kind: MacroDefKind::BuiltInDerive(expander),
303 local_inner: false,
304 },
287 krate: CrateId(0), 305 krate: CrateId(0),
288 kind: MacroCallKind::Attr(attr_id, name.to_string()), 306 kind: MacroCallKind::Attr(attr_id, name.to_string()),
289 }; 307 };
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index bd9223825..dddbbcdac 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -63,19 +63,19 @@ macro_rules! register_builtin {
63pub fn find_builtin_macro( 63pub fn find_builtin_macro(
64 ident: &name::Name, 64 ident: &name::Name,
65 krate: CrateId, 65 krate: CrateId,
66 ast_id: AstId<ast::MacroRules>, 66 ast_id: AstId<ast::Macro>,
67) -> Option<MacroDefId> { 67) -> Option<MacroDefId> {
68 let kind = find_by_name(ident)?; 68 let kind = find_by_name(ident)?;
69 69
70 match kind { 70 match kind {
71 Either::Left(kind) => Some(MacroDefId { 71 Either::Left(kind) => Some(MacroDefId {
72 krate: Some(krate), 72 krate,
73 ast_id: Some(ast_id), 73 ast_id: Some(ast_id),
74 kind: MacroDefKind::BuiltIn(kind), 74 kind: MacroDefKind::BuiltIn(kind),
75 local_inner: false, 75 local_inner: false,
76 }), 76 }),
77 Either::Right(kind) => Some(MacroDefId { 77 Either::Right(kind) => Some(MacroDefId {
78 krate: Some(krate), 78 krate,
79 ast_id: Some(ast_id), 79 ast_id: Some(ast_id),
80 kind: MacroDefKind::BuiltInEager(kind), 80 kind: MacroDefKind::BuiltInEager(kind),
81 local_inner: false, 81 local_inner: false,
@@ -515,24 +515,27 @@ mod tests {
515 fn expand_builtin_macro(ra_fixture: &str) -> String { 515 fn expand_builtin_macro(ra_fixture: &str) -> String {
516 let (db, file_id) = TestDB::with_single_file(&ra_fixture); 516 let (db, file_id) = TestDB::with_single_file(&ra_fixture);
517 let parsed = db.parse(file_id); 517 let parsed = db.parse(file_id);
518 let macro_rules: Vec<_> = 518 let mut macro_rules: Vec<_> =
519 parsed.syntax_node().descendants().filter_map(ast::MacroRules::cast).collect(); 519 parsed.syntax_node().descendants().filter_map(ast::MacroRules::cast).collect();
520 let macro_calls: Vec<_> = 520 let mut macro_calls: Vec<_> =
521 parsed.syntax_node().descendants().filter_map(ast::MacroCall::cast).collect(); 521 parsed.syntax_node().descendants().filter_map(ast::MacroCall::cast).collect();
522 522
523 let ast_id_map = db.ast_id_map(file_id.into()); 523 let ast_id_map = db.ast_id_map(file_id.into());
524 524
525 assert_eq!(macro_rules.len(), 1, "test must contain exactly 1 `macro_rules!`"); 525 assert_eq!(macro_rules.len(), 1, "test must contain exactly 1 `macro_rules!`");
526 assert_eq!(macro_calls.len(), 1, "test must contain exactly 1 macro call"); 526 assert_eq!(macro_calls.len(), 1, "test must contain exactly 1 macro call");
527 let expander = find_by_name(&macro_rules[0].name().unwrap().as_name()).unwrap(); 527 let macro_rules = ast::Macro::from(macro_rules.pop().unwrap());
528 let macro_call = macro_calls.pop().unwrap();
529
530 let expander = find_by_name(&macro_rules.name().unwrap().as_name()).unwrap();
528 531
529 let krate = CrateId(0); 532 let krate = CrateId(0);
530 let file_id = match expander { 533 let file_id = match expander {
531 Either::Left(expander) => { 534 Either::Left(expander) => {
532 // the first one should be a macro_rules 535 // the first one should be a macro_rules
533 let def = MacroDefId { 536 let def = MacroDefId {
534 krate: Some(CrateId(0)), 537 krate: CrateId(0),
535 ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(&macro_rules[0]))), 538 ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(&macro_rules))),
536 kind: MacroDefKind::BuiltIn(expander), 539 kind: MacroDefKind::BuiltIn(expander),
537 local_inner: false, 540 local_inner: false,
538 }; 541 };
@@ -542,7 +545,7 @@ mod tests {
542 krate, 545 krate,
543 kind: MacroCallKind::FnLike(AstId::new( 546 kind: MacroCallKind::FnLike(AstId::new(
544 file_id.into(), 547 file_id.into(),
545 ast_id_map.ast_id(&macro_calls[0]), 548 ast_id_map.ast_id(&macro_call),
546 )), 549 )),
547 }; 550 };
548 551
@@ -552,13 +555,13 @@ mod tests {
552 Either::Right(expander) => { 555 Either::Right(expander) => {
553 // the first one should be a macro_rules 556 // the first one should be a macro_rules
554 let def = MacroDefId { 557 let def = MacroDefId {
555 krate: Some(krate), 558 krate,
556 ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(&macro_rules[0]))), 559 ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(&macro_rules))),
557 kind: MacroDefKind::BuiltInEager(expander), 560 kind: MacroDefKind::BuiltInEager(expander),
558 local_inner: false, 561 local_inner: false,
559 }; 562 };
560 563
561 let args = macro_calls[0].token_tree().unwrap(); 564 let args = macro_call.token_tree().unwrap();
562 let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0; 565 let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0;
563 566
564 let arg_id = db.intern_eager_expansion({ 567 let arg_id = db.intern_eager_expansion({
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs
index 11b5b98c8..4477d867f 100644
--- a/crates/hir_expand/src/db.rs
+++ b/crates/hir_expand/src/db.rs
@@ -129,7 +129,10 @@ fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> {
129fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { 129fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> {
130 match id.kind { 130 match id.kind {
131 MacroDefKind::Declarative => { 131 MacroDefKind::Declarative => {
132 let macro_call = id.ast_id?.to_node(db); 132 let macro_call = match id.ast_id?.to_node(db) {
133 syntax::ast::Macro::MacroRules(mac) => mac,
134 syntax::ast::Macro::MacroDef(_) => return None,
135 };
133 let arg = macro_call.token_tree()?; 136 let arg = macro_call.token_tree()?;
134 let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| { 137 let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| {
135 log::warn!("fail on macro_def to token tree: {:#?}", arg); 138 log::warn!("fail on macro_def to token tree: {:#?}", arg);
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs
index 5d3fa0518..7ab0a5e52 100644
--- a/crates/hir_expand/src/hygiene.rs
+++ b/crates/hir_expand/src/hygiene.rs
@@ -29,8 +29,8 @@ impl Hygiene {
29 MacroCallId::LazyMacro(id) => { 29 MacroCallId::LazyMacro(id) => {
30 let loc = db.lookup_intern_macro(id); 30 let loc = db.lookup_intern_macro(id);
31 match loc.def.kind { 31 match loc.def.kind {
32 MacroDefKind::Declarative => (loc.def.krate, loc.def.local_inner), 32 MacroDefKind::Declarative => (Some(loc.def.krate), loc.def.local_inner),
33 MacroDefKind::BuiltIn(_) => (loc.def.krate, false), 33 MacroDefKind::BuiltIn(_) => (Some(loc.def.krate), false),
34 MacroDefKind::BuiltInDerive(_) => (None, false), 34 MacroDefKind::BuiltInDerive(_) => (None, false),
35 MacroDefKind::BuiltInEager(_) => (None, false), 35 MacroDefKind::BuiltInEager(_) => (None, false),
36 MacroDefKind::ProcMacro(_) => (None, false), 36 MacroDefKind::ProcMacro(_) => (None, false),
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index ae3086a95..d486186e5 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -145,7 +145,10 @@ impl HirFileId {
145 let arg_tt = loc.kind.arg(db)?; 145 let arg_tt = loc.kind.arg(db)?;
146 146
147 let def = loc.def.ast_id.and_then(|id| { 147 let def = loc.def.ast_id.and_then(|id| {
148 let def_tt = id.to_node(db).token_tree()?; 148 let def_tt = match id.to_node(db) {
149 ast::Macro::MacroRules(mac) => mac.token_tree()?,
150 ast::Macro::MacroDef(_) => return None,
151 };
149 Some(InFile::new(id.file_id, def_tt)) 152 Some(InFile::new(id.file_id, def_tt))
150 }); 153 });
151 154
@@ -221,14 +224,8 @@ impl From<EagerMacroId> for MacroCallId {
221 224
222#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 225#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
223pub struct MacroDefId { 226pub struct MacroDefId {
224 // FIXME: krate and ast_id are currently optional because we don't have a 227 pub krate: CrateId,
225 // definition location for built-in derives. There is one, though: the 228 pub ast_id: Option<AstId<ast::Macro>>,
226 // standard library defines them. The problem is that it uses the new
227 // `macro` syntax for this, which we don't support yet. As soon as we do
228 // (which will probably require touching this code), we can instead use
229 // that (and also remove the hacks for resolving built-in derives).
230 pub krate: Option<CrateId>,
231 pub ast_id: Option<AstId<ast::MacroRules>>,
232 pub kind: MacroDefKind, 229 pub kind: MacroDefKind,
233 230
234 pub local_inner: bool, 231 pub local_inner: bool,
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index 69d8e6803..7fb4caea3 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -37,9 +37,8 @@ impl Name {
37 Name(Repr::TupleField(idx)) 37 Name(Repr::TupleField(idx))
38 } 38 }
39 39
40 pub fn new_lifetime(lt: &syntax::SyntaxToken) -> Name { 40 pub fn new_lifetime(lt: &ast::Lifetime) -> Name {
41 assert_eq!(lt.kind(), syntax::SyntaxKind::LIFETIME); 41 Self::new_text(lt.text().clone())
42 Name(Repr::Text(lt.text().clone()))
43 } 42 }
44 43
45 /// Shortcut to create inline plain text name 44 /// Shortcut to create inline plain text name
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs
index 1c72f766e..14e18f5a1 100644
--- a/crates/hir_ty/src/diagnostics.rs
+++ b/crates/hir_ty/src/diagnostics.rs
@@ -6,6 +6,7 @@ mod decl_check;
6 6
7use std::{any::Any, fmt}; 7use std::{any::Any, fmt};
8 8
9use base_db::CrateId;
9use hir_def::{DefWithBodyId, ModuleDefId}; 10use hir_def::{DefWithBodyId, ModuleDefId};
10use hir_expand::diagnostics::{Diagnostic, DiagnosticCode, DiagnosticSink}; 11use hir_expand::diagnostics::{Diagnostic, DiagnosticCode, DiagnosticSink};
11use hir_expand::{name::Name, HirFileId, InFile}; 12use hir_expand::{name::Name, HirFileId, InFile};
@@ -18,12 +19,13 @@ pub use crate::diagnostics::expr::{record_literal_missing_fields, record_pattern
18 19
19pub fn validate_module_item( 20pub fn validate_module_item(
20 db: &dyn HirDatabase, 21 db: &dyn HirDatabase,
22 krate: CrateId,
21 owner: ModuleDefId, 23 owner: ModuleDefId,
22 sink: &mut DiagnosticSink<'_>, 24 sink: &mut DiagnosticSink<'_>,
23) { 25) {
24 let _p = profile::span("validate_module_item"); 26 let _p = profile::span("validate_module_item");
25 let mut validator = decl_check::DeclValidator::new(owner, sink); 27 let mut validator = decl_check::DeclValidator::new(db, krate, sink);
26 validator.validate_item(db); 28 validator.validate_item(owner);
27} 29}
28 30
29pub fn validate_body(db: &dyn HirDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) { 31pub fn validate_body(db: &dyn HirDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) {
@@ -407,7 +409,7 @@ mod tests {
407 for (module_id, _) in crate_def_map.modules.iter() { 409 for (module_id, _) in crate_def_map.modules.iter() {
408 for decl in crate_def_map[module_id].scope.declarations() { 410 for decl in crate_def_map[module_id].scope.declarations() {
409 let mut sink = DiagnosticSinkBuilder::new().build(&mut cb); 411 let mut sink = DiagnosticSinkBuilder::new().build(&mut cb);
410 validate_module_item(self, decl, &mut sink); 412 validate_module_item(self, krate, decl, &mut sink);
411 413
412 if let ModuleDefId::FunctionId(f) = decl { 414 if let ModuleDefId::FunctionId(f) = decl {
413 fns.push(f) 415 fns.push(f)
@@ -419,7 +421,12 @@ mod tests {
419 for item in impl_data.items.iter() { 421 for item in impl_data.items.iter() {
420 if let AssocItemId::FunctionId(f) = item { 422 if let AssocItemId::FunctionId(f) = item {
421 let mut sink = DiagnosticSinkBuilder::new().build(&mut cb); 423 let mut sink = DiagnosticSinkBuilder::new().build(&mut cb);
422 validate_module_item(self, ModuleDefId::FunctionId(*f), &mut sink); 424 validate_module_item(
425 self,
426 krate,
427 ModuleDefId::FunctionId(*f),
428 &mut sink,
429 );
423 fns.push(*f) 430 fns.push(*f)
424 } 431 }
425 } 432 }
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index 25587e116..eaeb6899f 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -12,6 +12,7 @@
12 12
13mod case_conv; 13mod case_conv;
14 14
15use base_db::CrateId;
15use hir_def::{ 16use hir_def::{
16 adt::VariantData, 17 adt::VariantData,
17 expr::{Pat, PatId}, 18 expr::{Pat, PatId},
@@ -40,7 +41,8 @@ mod allow {
40} 41}
41 42
42pub(super) struct DeclValidator<'a, 'b: 'a> { 43pub(super) struct DeclValidator<'a, 'b: 'a> {
43 owner: ModuleDefId, 44 db: &'a dyn HirDatabase,
45 krate: CrateId,
44 sink: &'a mut DiagnosticSink<'b>, 46 sink: &'a mut DiagnosticSink<'b>,
45} 47}
46 48
@@ -53,26 +55,27 @@ struct Replacement {
53 55
54impl<'a, 'b> DeclValidator<'a, 'b> { 56impl<'a, 'b> DeclValidator<'a, 'b> {
55 pub(super) fn new( 57 pub(super) fn new(
56 owner: ModuleDefId, 58 db: &'a dyn HirDatabase,
59 krate: CrateId,
57 sink: &'a mut DiagnosticSink<'b>, 60 sink: &'a mut DiagnosticSink<'b>,
58 ) -> DeclValidator<'a, 'b> { 61 ) -> DeclValidator<'a, 'b> {
59 DeclValidator { owner, sink } 62 DeclValidator { db, krate, sink }
60 } 63 }
61 64
62 pub(super) fn validate_item(&mut self, db: &dyn HirDatabase) { 65 pub(super) fn validate_item(&mut self, item: ModuleDefId) {
63 match self.owner { 66 match item {
64 ModuleDefId::FunctionId(func) => self.validate_func(db, func), 67 ModuleDefId::FunctionId(func) => self.validate_func(func),
65 ModuleDefId::AdtId(adt) => self.validate_adt(db, adt), 68 ModuleDefId::AdtId(adt) => self.validate_adt(adt),
66 ModuleDefId::ConstId(const_id) => self.validate_const(db, const_id), 69 ModuleDefId::ConstId(const_id) => self.validate_const(const_id),
67 ModuleDefId::StaticId(static_id) => self.validate_static(db, static_id), 70 ModuleDefId::StaticId(static_id) => self.validate_static(static_id),
68 _ => return, 71 _ => return,
69 } 72 }
70 } 73 }
71 74
72 fn validate_adt(&mut self, db: &dyn HirDatabase, adt: AdtId) { 75 fn validate_adt(&mut self, adt: AdtId) {
73 match adt { 76 match adt {
74 AdtId::StructId(struct_id) => self.validate_struct(db, struct_id), 77 AdtId::StructId(struct_id) => self.validate_struct(struct_id),
75 AdtId::EnumId(enum_id) => self.validate_enum(db, enum_id), 78 AdtId::EnumId(enum_id) => self.validate_enum(enum_id),
76 AdtId::UnionId(_) => { 79 AdtId::UnionId(_) => {
77 // Unions aren't yet supported by this validator. 80 // Unions aren't yet supported by this validator.
78 } 81 }
@@ -82,27 +85,27 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
82 /// Checks whether not following the convention is allowed for this item. 85 /// Checks whether not following the convention is allowed for this item.
83 /// 86 ///
84 /// Currently this method doesn't check parent attributes. 87 /// Currently this method doesn't check parent attributes.
85 fn allowed(&self, db: &dyn HirDatabase, id: AttrDefId, allow_name: &str) -> bool { 88 fn allowed(&self, id: AttrDefId, allow_name: &str) -> bool {
86 db.attrs(id).by_key("allow").tt_values().any(|tt| tt.to_string().contains(allow_name)) 89 self.db.attrs(id).by_key("allow").tt_values().any(|tt| tt.to_string().contains(allow_name))
87 } 90 }
88 91
89 fn validate_func(&mut self, db: &dyn HirDatabase, func: FunctionId) { 92 fn validate_func(&mut self, func: FunctionId) {
90 let data = db.function_data(func); 93 let data = self.db.function_data(func);
91 if data.is_extern { 94 if data.is_extern {
92 mark::hit!(extern_func_incorrect_case_ignored); 95 mark::hit!(extern_func_incorrect_case_ignored);
93 return; 96 return;
94 } 97 }
95 98
96 let body = db.body(func.into()); 99 let body = self.db.body(func.into());
97 100
98 // Recursively validate inner scope items, such as static variables and constants. 101 // Recursively validate inner scope items, such as static variables and constants.
99 for (item_id, _) in body.item_scope.values() { 102 for (item_id, _) in body.item_scope.values() {
100 let mut validator = DeclValidator::new(item_id, self.sink); 103 let mut validator = DeclValidator::new(self.db, self.krate, self.sink);
101 validator.validate_item(db); 104 validator.validate_item(item_id);
102 } 105 }
103 106
104 // Check whether non-snake case identifiers are allowed for this function. 107 // Check whether non-snake case identifiers are allowed for this function.
105 if self.allowed(db, func.into(), allow::NON_SNAKE_CASE) { 108 if self.allowed(func.into(), allow::NON_SNAKE_CASE) {
106 return; 109 return;
107 } 110 }
108 111
@@ -169,11 +172,10 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
169 // If there is at least one element to spawn a warning on, go to the source map and generate a warning. 172 // If there is at least one element to spawn a warning on, go to the source map and generate a warning.
170 self.create_incorrect_case_diagnostic_for_func( 173 self.create_incorrect_case_diagnostic_for_func(
171 func, 174 func,
172 db,
173 fn_name_replacement, 175 fn_name_replacement,
174 fn_param_replacements, 176 fn_param_replacements,
175 ); 177 );
176 self.create_incorrect_case_diagnostic_for_variables(func, db, pats_replacements); 178 self.create_incorrect_case_diagnostic_for_variables(func, pats_replacements);
177 } 179 }
178 180
179 /// Given the information about incorrect names in the function declaration, looks up into the source code 181 /// Given the information about incorrect names in the function declaration, looks up into the source code
@@ -181,7 +183,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
181 fn create_incorrect_case_diagnostic_for_func( 183 fn create_incorrect_case_diagnostic_for_func(
182 &mut self, 184 &mut self,
183 func: FunctionId, 185 func: FunctionId,
184 db: &dyn HirDatabase,
185 fn_name_replacement: Option<Replacement>, 186 fn_name_replacement: Option<Replacement>,
186 fn_param_replacements: Vec<Replacement>, 187 fn_param_replacements: Vec<Replacement>,
187 ) { 188 ) {
@@ -190,8 +191,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
190 return; 191 return;
191 } 192 }
192 193
193 let fn_loc = func.lookup(db.upcast()); 194 let fn_loc = func.lookup(self.db.upcast());
194 let fn_src = fn_loc.source(db.upcast()); 195 let fn_src = fn_loc.source(self.db.upcast());
195 196
196 // Diagnostic for function name. 197 // Diagnostic for function name.
197 if let Some(replacement) = fn_name_replacement { 198 if let Some(replacement) = fn_name_replacement {
@@ -282,7 +283,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
282 fn create_incorrect_case_diagnostic_for_variables( 283 fn create_incorrect_case_diagnostic_for_variables(
283 &mut self, 284 &mut self,
284 func: FunctionId, 285 func: FunctionId,
285 db: &dyn HirDatabase,
286 pats_replacements: Vec<(PatId, Replacement)>, 286 pats_replacements: Vec<(PatId, Replacement)>,
287 ) { 287 ) {
288 // XXX: only look at source_map if we do have missing fields 288 // XXX: only look at source_map if we do have missing fields
@@ -290,12 +290,12 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
290 return; 290 return;
291 } 291 }
292 292
293 let (_, source_map) = db.body_with_source_map(func.into()); 293 let (_, source_map) = self.db.body_with_source_map(func.into());
294 294
295 for (id, replacement) in pats_replacements { 295 for (id, replacement) in pats_replacements {
296 if let Ok(source_ptr) = source_map.pat_syntax(id) { 296 if let Ok(source_ptr) = source_map.pat_syntax(id) {
297 if let Some(expr) = source_ptr.value.as_ref().left() { 297 if let Some(expr) = source_ptr.value.as_ref().left() {
298 let root = source_ptr.file_syntax(db.upcast()); 298 let root = source_ptr.file_syntax(self.db.upcast());
299 if let ast::Pat::IdentPat(ident_pat) = expr.to_node(&root) { 299 if let ast::Pat::IdentPat(ident_pat) = expr.to_node(&root) {
300 let parent = match ident_pat.syntax().parent() { 300 let parent = match ident_pat.syntax().parent() {
301 Some(parent) => parent, 301 Some(parent) => parent,
@@ -333,12 +333,11 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
333 } 333 }
334 } 334 }
335 335
336 fn validate_struct(&mut self, db: &dyn HirDatabase, struct_id: StructId) { 336 fn validate_struct(&mut self, struct_id: StructId) {
337 let data = db.struct_data(struct_id); 337 let data = self.db.struct_data(struct_id);
338 338
339 let non_camel_case_allowed = 339 let non_camel_case_allowed = self.allowed(struct_id.into(), allow::NON_CAMEL_CASE_TYPES);
340 self.allowed(db, struct_id.into(), allow::NON_CAMEL_CASE_TYPES); 340 let non_snake_case_allowed = self.allowed(struct_id.into(), allow::NON_SNAKE_CASE);
341 let non_snake_case_allowed = self.allowed(db, struct_id.into(), allow::NON_SNAKE_CASE);
342 341
343 // Check the structure name. 342 // Check the structure name.
344 let struct_name = data.name.to_string(); 343 let struct_name = data.name.to_string();
@@ -379,7 +378,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
379 // If there is at least one element to spawn a warning on, go to the source map and generate a warning. 378 // If there is at least one element to spawn a warning on, go to the source map and generate a warning.
380 self.create_incorrect_case_diagnostic_for_struct( 379 self.create_incorrect_case_diagnostic_for_struct(
381 struct_id, 380 struct_id,
382 db,
383 struct_name_replacement, 381 struct_name_replacement,
384 struct_fields_replacements, 382 struct_fields_replacements,
385 ); 383 );
@@ -390,7 +388,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
390 fn create_incorrect_case_diagnostic_for_struct( 388 fn create_incorrect_case_diagnostic_for_struct(
391 &mut self, 389 &mut self,
392 struct_id: StructId, 390 struct_id: StructId,
393 db: &dyn HirDatabase,
394 struct_name_replacement: Option<Replacement>, 391 struct_name_replacement: Option<Replacement>,
395 struct_fields_replacements: Vec<Replacement>, 392 struct_fields_replacements: Vec<Replacement>,
396 ) { 393 ) {
@@ -399,8 +396,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
399 return; 396 return;
400 } 397 }
401 398
402 let struct_loc = struct_id.lookup(db.upcast()); 399 let struct_loc = struct_id.lookup(self.db.upcast());
403 let struct_src = struct_loc.source(db.upcast()); 400 let struct_src = struct_loc.source(self.db.upcast());
404 401
405 if let Some(replacement) = struct_name_replacement { 402 if let Some(replacement) = struct_name_replacement {
406 let ast_ptr = match struct_src.value.name() { 403 let ast_ptr = match struct_src.value.name() {
@@ -473,11 +470,11 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
473 } 470 }
474 } 471 }
475 472
476 fn validate_enum(&mut self, db: &dyn HirDatabase, enum_id: EnumId) { 473 fn validate_enum(&mut self, enum_id: EnumId) {
477 let data = db.enum_data(enum_id); 474 let data = self.db.enum_data(enum_id);
478 475
479 // Check whether non-camel case names are allowed for this enum. 476 // Check whether non-camel case names are allowed for this enum.
480 if self.allowed(db, enum_id.into(), allow::NON_CAMEL_CASE_TYPES) { 477 if self.allowed(enum_id.into(), allow::NON_CAMEL_CASE_TYPES) {
481 return; 478 return;
482 } 479 }
483 480
@@ -512,7 +509,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
512 // If there is at least one element to spawn a warning on, go to the source map and generate a warning. 509 // If there is at least one element to spawn a warning on, go to the source map and generate a warning.
513 self.create_incorrect_case_diagnostic_for_enum( 510 self.create_incorrect_case_diagnostic_for_enum(
514 enum_id, 511 enum_id,
515 db,
516 enum_name_replacement, 512 enum_name_replacement,
517 enum_fields_replacements, 513 enum_fields_replacements,
518 ) 514 )
@@ -523,7 +519,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
523 fn create_incorrect_case_diagnostic_for_enum( 519 fn create_incorrect_case_diagnostic_for_enum(
524 &mut self, 520 &mut self,
525 enum_id: EnumId, 521 enum_id: EnumId,
526 db: &dyn HirDatabase,
527 enum_name_replacement: Option<Replacement>, 522 enum_name_replacement: Option<Replacement>,
528 enum_variants_replacements: Vec<Replacement>, 523 enum_variants_replacements: Vec<Replacement>,
529 ) { 524 ) {
@@ -532,8 +527,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
532 return; 527 return;
533 } 528 }
534 529
535 let enum_loc = enum_id.lookup(db.upcast()); 530 let enum_loc = enum_id.lookup(self.db.upcast());
536 let enum_src = enum_loc.source(db.upcast()); 531 let enum_src = enum_loc.source(self.db.upcast());
537 532
538 if let Some(replacement) = enum_name_replacement { 533 if let Some(replacement) = enum_name_replacement {
539 let ast_ptr = match enum_src.value.name() { 534 let ast_ptr = match enum_src.value.name() {
@@ -608,10 +603,10 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
608 } 603 }
609 } 604 }
610 605
611 fn validate_const(&mut self, db: &dyn HirDatabase, const_id: ConstId) { 606 fn validate_const(&mut self, const_id: ConstId) {
612 let data = db.const_data(const_id); 607 let data = self.db.const_data(const_id);
613 608
614 if self.allowed(db, const_id.into(), allow::NON_UPPER_CASE_GLOBAL) { 609 if self.allowed(const_id.into(), allow::NON_UPPER_CASE_GLOBAL) {
615 return; 610 return;
616 } 611 }
617 612
@@ -632,8 +627,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
632 return; 627 return;
633 }; 628 };
634 629
635 let const_loc = const_id.lookup(db.upcast()); 630 let const_loc = const_id.lookup(self.db.upcast());
636 let const_src = const_loc.source(db.upcast()); 631 let const_src = const_loc.source(self.db.upcast());
637 632
638 let ast_ptr = match const_src.value.name() { 633 let ast_ptr = match const_src.value.name() {
639 Some(name) => name, 634 Some(name) => name,
@@ -652,14 +647,14 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
652 self.sink.push(diagnostic); 647 self.sink.push(diagnostic);
653 } 648 }
654 649
655 fn validate_static(&mut self, db: &dyn HirDatabase, static_id: StaticId) { 650 fn validate_static(&mut self, static_id: StaticId) {
656 let data = db.static_data(static_id); 651 let data = self.db.static_data(static_id);
657 if data.is_extern { 652 if data.is_extern {
658 mark::hit!(extern_static_incorrect_case_ignored); 653 mark::hit!(extern_static_incorrect_case_ignored);
659 return; 654 return;
660 } 655 }
661 656
662 if self.allowed(db, static_id.into(), allow::NON_UPPER_CASE_GLOBAL) { 657 if self.allowed(static_id.into(), allow::NON_UPPER_CASE_GLOBAL) {
663 return; 658 return;
664 } 659 }
665 660
@@ -680,8 +675,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
680 return; 675 return;
681 }; 676 };
682 677
683 let static_loc = static_id.lookup(db.upcast()); 678 let static_loc = static_id.lookup(self.db.upcast());
684 let static_src = static_loc.source(db.upcast()); 679 let static_src = static_loc.source(self.db.upcast());
685 680
686 let ast_ptr = match static_src.value.name() { 681 let ast_ptr = match static_src.value.name() {
687 Some(name) => name, 682 Some(name) => name,
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index de97ec3c2..a7656b864 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -686,6 +686,8 @@ mod clone {
686 trait Clone { 686 trait Clone {
687 fn clone(&self) -> Self; 687 fn clone(&self) -> Self;
688 } 688 }
689 #[rustc_builtin_macro]
690 macro Clone {}
689} 691}
690"#, 692"#,
691 ); 693 );
@@ -702,6 +704,8 @@ mod clone {
702 trait Clone { 704 trait Clone {
703 fn clone(&self) -> Self; 705 fn clone(&self) -> Self;
704 } 706 }
707 #[rustc_builtin_macro]
708 macro Clone {}
705} 709}
706#[derive(Clone)] 710#[derive(Clone)]
707pub struct S; 711pub struct S;
@@ -737,6 +741,8 @@ mod clone {
737 trait Clone { 741 trait Clone {
738 fn clone(&self) -> Self; 742 fn clone(&self) -> Self;
739 } 743 }
744 #[rustc_builtin_macro]
745 macro Clone {}
740} 746}
741"#, 747"#,
742 ); 748 );
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs
index 73fc73619..48acb8c93 100644
--- a/crates/ide/src/display/navigation_target.rs
+++ b/crates/ide/src/display/navigation_target.rs
@@ -1,15 +1,13 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use either::Either; 3use either::Either;
4use hir::{ 4use hir::{AssocItem, Documentation, FieldSource, HasAttrs, HasSource, InFile, ModuleSource};
5 AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirFileId, InFile, ModuleSource,
6};
7use ide_db::base_db::{FileId, SourceDatabase}; 5use ide_db::base_db::{FileId, SourceDatabase};
8use ide_db::{defs::Definition, RootDatabase}; 6use ide_db::{defs::Definition, RootDatabase};
9use syntax::{ 7use syntax::{
10 ast::{self, NameOwner}, 8 ast::{self, NameOwner},
11 match_ast, AstNode, SmolStr, 9 match_ast, AstNode, SmolStr,
12 SyntaxKind::{self, IDENT_PAT, TYPE_PARAM}, 10 SyntaxKind::{self, IDENT_PAT, LIFETIME_PARAM, TYPE_PARAM},
13 TextRange, 11 TextRange,
14}; 12};
15 13
@@ -119,25 +117,6 @@ impl NavigationTarget {
119 ) 117 )
120 } 118 }
121 119
122 /// Allows `NavigationTarget` to be created from a `DocCommentsOwner` and a `NameOwner`
123 pub(crate) fn from_doc_commented(
124 db: &RootDatabase,
125 named: InFile<&dyn ast::NameOwner>,
126 node: InFile<&dyn ast::DocCommentsOwner>,
127 ) -> NavigationTarget {
128 let name =
129 named.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_"));
130 let frange = node.map(|it| it.syntax()).original_file_range(db);
131
132 NavigationTarget::from_syntax(
133 frange.file_id,
134 name,
135 None,
136 frange.range,
137 node.value.syntax().kind(),
138 )
139 }
140
141 fn from_syntax( 120 fn from_syntax(
142 file_id: FileId, 121 file_id: FileId,
143 name: SmolStr, 122 name: SmolStr,
@@ -168,7 +147,7 @@ impl ToNav for FileSymbol {
168 focus_range: self.name_range, 147 focus_range: self.name_range,
169 container_name: self.container_name.clone(), 148 container_name: self.container_name.clone(),
170 description: description_from_symbol(db, self), 149 description: description_from_symbol(db, self),
171 docs: docs_from_symbol(db, self), 150 docs: None,
172 } 151 }
173 } 152 }
174} 153}
@@ -190,6 +169,7 @@ impl TryToNav for Definition {
190 Definition::SelfType(it) => Some(it.to_nav(db)), 169 Definition::SelfType(it) => Some(it.to_nav(db)),
191 Definition::Local(it) => Some(it.to_nav(db)), 170 Definition::Local(it) => Some(it.to_nav(db)),
192 Definition::TypeParam(it) => Some(it.to_nav(db)), 171 Definition::TypeParam(it) => Some(it.to_nav(db)),
172 Definition::LifetimeParam(it) => Some(it.to_nav(db)),
193 } 173 }
194 } 174 }
195} 175}
@@ -252,7 +232,7 @@ impl ToNav for hir::Module {
252 } 232 }
253} 233}
254 234
255impl ToNav for hir::ImplDef { 235impl ToNav for hir::Impl {
256 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { 236 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
257 let src = self.source(db); 237 let src = self.source(db);
258 let derive_attr = self.is_builtin_derive(db); 238 let derive_attr = self.is_builtin_derive(db);
@@ -384,28 +364,21 @@ impl ToNav for hir::TypeParam {
384 } 364 }
385} 365}
386 366
387pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<Documentation> { 367impl ToNav for hir::LifetimeParam {
388 let parse = db.parse(symbol.file_id); 368 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
389 let node = symbol.ptr.to_node(parse.tree().syntax()); 369 let src = self.source(db);
390 let file_id = HirFileId::from(symbol.file_id); 370 let full_range = src.value.syntax().text_range();
391 371 NavigationTarget {
392 let it = match_ast! { 372 file_id: src.file_id.original_file(db),
393 match node { 373 name: self.name(db).to_string().into(),
394 ast::Fn(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), 374 kind: LIFETIME_PARAM,
395 ast::Struct(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), 375 full_range,
396 ast::Enum(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), 376 focus_range: Some(full_range),
397 ast::Trait(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), 377 container_name: None,
398 ast::Module(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), 378 description: None,
399 ast::TypeAlias(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), 379 docs: None,
400 ast::Const(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
401 ast::Static(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
402 ast::RecordField(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
403 ast::Variant(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
404 ast::MacroCall(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
405 _ => return None,
406 } 380 }
407 }; 381 }
408 it.docs()
409} 382}
410 383
411/// Get a description of a symbol. 384/// Get a description of a symbol.
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index 10263537a..79c081cac 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -112,7 +112,7 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
112 .as_assoc_item(db) 112 .as_assoc_item(db)
113 .and_then(|assoc| match assoc.container(db) { 113 .and_then(|assoc| match assoc.container(db) {
114 AssocItemContainer::Trait(t) => Some(t.into()), 114 AssocItemContainer::Trait(t) => Some(t.into()),
115 AssocItemContainer::ImplDef(impld) => { 115 AssocItemContainer::Impl(impld) => {
116 impld.target_ty(db).as_adt().map(|adt| adt.into()) 116 impld.target_ty(db).as_adt().map(|adt| adt.into())
117 } 117 }
118 }) 118 })
@@ -190,7 +190,10 @@ fn rewrite_intra_doc_link(
190 }, 190 },
191 Definition::Macro(it) => it.resolve_doc_path(db, link, ns), 191 Definition::Macro(it) => it.resolve_doc_path(db, link, ns),
192 Definition::Field(it) => it.resolve_doc_path(db, link, ns), 192 Definition::Field(it) => it.resolve_doc_path(db, link, ns),
193 Definition::SelfType(_) | Definition::Local(_) | Definition::TypeParam(_) => return None, 193 Definition::SelfType(_)
194 | Definition::Local(_)
195 | Definition::TypeParam(_)
196 | Definition::LifetimeParam(_) => return None,
194 }?; 197 }?;
195 let krate = resolved.module(db)?.krate(); 198 let krate = resolved.module(db)?.krate();
196 let canonical_path = resolved.canonical_path(db)?; 199 let canonical_path = resolved.canonical_path(db)?;
diff --git a/crates/ide/src/extend_selection.rs b/crates/ide/src/extend_selection.rs
index 0971f7701..6f3022dfd 100644
--- a/crates/ide/src/extend_selection.rs
+++ b/crates/ide/src/extend_selection.rs
@@ -237,7 +237,7 @@ fn pick_best(l: SyntaxToken, r: SyntaxToken) -> SyntaxToken {
237 fn priority(n: &SyntaxToken) -> usize { 237 fn priority(n: &SyntaxToken) -> usize {
238 match n.kind() { 238 match n.kind() {
239 WHITESPACE => 0, 239 WHITESPACE => 0,
240 IDENT | T![self] | T![super] | T![crate] | LIFETIME => 2, 240 IDENT | T![self] | T![super] | T![crate] | LIFETIME_IDENT => 2,
241 _ => 1, 241 _ => 1,
242 } 242 }
243 } 243 }
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index b9810457f..173509b08 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1,3 +1,4 @@
1use either::Either;
1use hir::Semantics; 2use hir::Semantics;
2use ide_db::{ 3use ide_db::{
3 base_db::FileId, 4 base_db::FileId,
@@ -33,7 +34,7 @@ pub(crate) fn goto_definition(
33 let nav_targets = match_ast! { 34 let nav_targets = match_ast! {
34 match parent { 35 match parent {
35 ast::NameRef(name_ref) => { 36 ast::NameRef(name_ref) => {
36 reference_definition(&sema, &name_ref).to_vec() 37 reference_definition(&sema, Either::Right(&name_ref)).to_vec()
37 }, 38 },
38 ast::Name(name) => { 39 ast::Name(name) => {
39 let def = NameClass::classify(&sema, &name)?.referenced_or_defined(sema.db); 40 let def = NameClass::classify(&sema, &name)?.referenced_or_defined(sema.db);
@@ -53,6 +54,13 @@ pub(crate) fn goto_definition(
53 let self_param = func.param_list()?.self_param()?; 54 let self_param = func.param_list()?.self_param()?;
54 vec![self_to_nav_target(self_param, position.file_id)?] 55 vec![self_to_nav_target(self_param, position.file_id)?]
55 }, 56 },
57 ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, &lt) {
58 let def = name_class.referenced_or_defined(sema.db);
59 let nav = def.try_to_nav(sema.db)?;
60 vec![nav]
61 } else {
62 reference_definition(&sema, Either::Left(&lt)).to_vec()
63 },
56 _ => return None, 64 _ => return None,
57 } 65 }
58 }; 66 };
@@ -64,7 +72,7 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
64 return tokens.max_by_key(priority); 72 return tokens.max_by_key(priority);
65 fn priority(n: &SyntaxToken) -> usize { 73 fn priority(n: &SyntaxToken) -> usize {
66 match n.kind() { 74 match n.kind() {
67 IDENT | INT_NUMBER | T![self] => 2, 75 IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] => 2,
68 kind if kind.is_trivia() => 0, 76 kind if kind.is_trivia() => 0,
69 _ => 1, 77 _ => 1,
70 } 78 }
@@ -102,9 +110,12 @@ impl ReferenceResult {
102 110
103pub(crate) fn reference_definition( 111pub(crate) fn reference_definition(
104 sema: &Semantics<RootDatabase>, 112 sema: &Semantics<RootDatabase>,
105 name_ref: &ast::NameRef, 113 name_ref: Either<&ast::Lifetime, &ast::NameRef>,
106) -> ReferenceResult { 114) -> ReferenceResult {
107 let name_kind = NameRefClass::classify(sema, name_ref); 115 let name_kind = name_ref.either(
116 |lifetime| NameRefClass::classify_lifetime(sema, lifetime),
117 |name_ref| NameRefClass::classify(sema, name_ref),
118 );
108 if let Some(def) = name_kind { 119 if let Some(def) = name_kind {
109 let def = def.referenced(sema.db); 120 let def = def.referenced(sema.db);
110 return match def.try_to_nav(sema.db) { 121 return match def.try_to_nav(sema.db) {
@@ -114,10 +125,9 @@ pub(crate) fn reference_definition(
114 } 125 }
115 126
116 // Fallback index based approach: 127 // Fallback index based approach:
117 let navs = symbol_index::index_resolve(sema.db, name_ref) 128 let name = name_ref.either(ast::Lifetime::text, ast::NameRef::text);
118 .into_iter() 129 let navs =
119 .map(|s| s.to_nav(sema.db)) 130 symbol_index::index_resolve(sema.db, name).into_iter().map(|s| s.to_nav(sema.db)).collect();
120 .collect();
121 ReferenceResult::Approximate(navs) 131 ReferenceResult::Approximate(navs)
122} 132}
123 133
@@ -1036,4 +1046,35 @@ impl Foo {
1036}"#, 1046}"#,
1037 ) 1047 )
1038 } 1048 }
1049
1050 #[test]
1051 fn goto_lifetime_param_on_decl() {
1052 check(
1053 r#"
1054fn foo<'foobar<|>>(_: &'foobar ()) {
1055 //^^^^^^^
1056}"#,
1057 )
1058 }
1059
1060 #[test]
1061 fn goto_lifetime_param_decl() {
1062 check(
1063 r#"
1064fn foo<'foobar>(_: &'foobar<|> ()) {
1065 //^^^^^^^
1066}"#,
1067 )
1068 }
1069
1070 #[test]
1071 fn goto_lifetime_param_decl_nested() {
1072 check(
1073 r#"
1074fn foo<'foobar>(_: &'foobar ()) {
1075 fn foo<'foobar>(_: &'foobar<|> ()) {}
1076 //^^^^^^^
1077}"#,
1078 )
1079 }
1039} 1080}
diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs
index 529004878..6eac39639 100644
--- a/crates/ide/src/goto_implementation.rs
+++ b/crates/ide/src/goto_implementation.rs
@@ -1,4 +1,4 @@
1use hir::{Crate, ImplDef, Semantics}; 1use hir::{Crate, Impl, Semantics};
2use ide_db::RootDatabase; 2use ide_db::RootDatabase;
3use syntax::{algo::find_node_at_offset, ast, AstNode}; 3use syntax::{algo::find_node_at_offset, ast, AstNode};
4 4
@@ -49,7 +49,7 @@ fn impls_for_def(
49 ast::AdtDef::Union(def) => sema.to_def(def)?.ty(sema.db), 49 ast::AdtDef::Union(def) => sema.to_def(def)?.ty(sema.db),
50 }; 50 };
51 51
52 let impls = ImplDef::all_in_crate(sema.db, krate); 52 let impls = Impl::all_in_crate(sema.db, krate);
53 53
54 Some( 54 Some(
55 impls 55 impls
@@ -67,7 +67,7 @@ fn impls_for_trait(
67) -> Option<Vec<NavigationTarget>> { 67) -> Option<Vec<NavigationTarget>> {
68 let tr = sema.to_def(node)?; 68 let tr = sema.to_def(node)?;
69 69
70 let impls = ImplDef::for_trait(sema.db, krate, tr); 70 let impls = Impl::for_trait(sema.db, krate, tr);
71 71
72 Some(impls.into_iter().map(|imp| imp.to_nav(sema.db)).collect()) 72 Some(impls.into_iter().map(|imp| imp.to_nav(sema.db)).collect())
73} 73}
@@ -221,6 +221,8 @@ struct Foo<|>;
221mod marker { 221mod marker {
222 trait Copy {} 222 trait Copy {}
223} 223}
224#[rustc_builtin_macro]
225macro Copy {}
224"#, 226"#,
225 ); 227 );
226 } 228 }
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index c03dd74e4..da6bb726a 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -295,7 +295,7 @@ fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option<String>
295 Definition::ModuleDef(md) => match md { 295 Definition::ModuleDef(md) => match md {
296 ModuleDef::Function(f) => match f.as_assoc_item(db)?.container(db) { 296 ModuleDef::Function(f) => match f.as_assoc_item(db)?.container(db) {
297 AssocItemContainer::Trait(t) => Some(t.name(db)), 297 AssocItemContainer::Trait(t) => Some(t.name(db)),
298 AssocItemContainer::ImplDef(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)), 298 AssocItemContainer::Impl(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)),
299 }, 299 },
300 ModuleDef::EnumVariant(e) => Some(e.parent_enum(db).name(db)), 300 ModuleDef::EnumVariant(e) => Some(e.parent_enum(db).name(db)),
301 _ => None, 301 _ => None,
@@ -370,7 +370,7 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> {
370 Adt::Enum(it) => from_def_source(db, it, mod_path), 370 Adt::Enum(it) => from_def_source(db, it, mod_path),
371 }) 371 })
372 } 372 }
373 Definition::TypeParam(_) => { 373 Definition::TypeParam(_) | Definition::LifetimeParam(_) => {
374 // FIXME: Hover for generic param 374 // FIXME: Hover for generic param
375 None 375 None
376 } 376 }
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 71068cac2..c5c652cda 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -528,6 +528,13 @@ impl Analysis {
528 self.with_db(|db| references::rename::rename(db, position, new_name)) 528 self.with_db(|db| references::rename::rename(db, position, new_name))
529 } 529 }
530 530
531 pub fn prepare_rename(
532 &self,
533 position: FilePosition,
534 ) -> Cancelable<Result<RangeInfo<()>, RenameError>> {
535 self.with_db(|db| references::rename::prepare_rename(db, position))
536 }
537
531 pub fn structural_search_replace( 538 pub fn structural_search_replace(
532 &self, 539 &self,
533 query: &str, 540 query: &str,
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index 675957fff..98190a86b 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -130,6 +130,8 @@ pub(crate) fn find_all_refs(
130 kind = ReferenceKind::FieldShorthandForLocal; 130 kind = ReferenceKind::FieldShorthandForLocal;
131 } 131 }
132 } 132 }
133 } else if let Definition::LifetimeParam(_) = def {
134 kind = ReferenceKind::Lifetime;
133 }; 135 };
134 136
135 let declaration = Declaration { nav, kind, access: decl_access(&def, &syntax, decl_range) }; 137 let declaration = Declaration { nav, kind, access: decl_access(&def, &syntax, decl_range) };
@@ -148,11 +150,29 @@ fn find_name(
148 let range = name.syntax().text_range(); 150 let range = name.syntax().text_range();
149 return Some(RangeInfo::new(range, def)); 151 return Some(RangeInfo::new(range, def));
150 } 152 }
151 let name_ref = 153
152 sema.find_node_at_offset_with_descend::<ast::NameRef>(&syntax, position.offset)?; 154 let (text_range, def) = if let Some(lifetime) =
153 let def = NameRefClass::classify(sema, &name_ref)?.referenced(sema.db); 155 sema.find_node_at_offset_with_descend::<ast::Lifetime>(&syntax, position.offset)
154 let range = name_ref.syntax().text_range(); 156 {
155 Some(RangeInfo::new(range, def)) 157 if let Some(def) = NameRefClass::classify_lifetime(sema, &lifetime)
158 .map(|class| NameRefClass::referenced(class, sema.db))
159 {
160 (lifetime.syntax().text_range(), def)
161 } else {
162 (
163 lifetime.syntax().text_range(),
164 NameClass::classify_lifetime(sema, &lifetime)?.referenced_or_defined(sema.db),
165 )
166 }
167 } else {
168 let name_ref =
169 sema.find_node_at_offset_with_descend::<ast::NameRef>(&syntax, position.offset)?;
170 (
171 name_ref.syntax().text_range(),
172 NameRefClass::classify(sema, &name_ref)?.referenced(sema.db),
173 )
174 };
175 Some(RangeInfo::new(text_range, def))
156} 176}
157 177
158fn decl_access(def: &Definition, syntax: &SyntaxNode, range: TextRange) -> Option<ReferenceAccess> { 178fn decl_access(def: &Definition, syntax: &SyntaxNode, range: TextRange) -> Option<ReferenceAccess> {
@@ -1005,4 +1025,65 @@ impl Foo {
1005 } 1025 }
1006 expect.assert_eq(&actual) 1026 expect.assert_eq(&actual)
1007 } 1027 }
1028
1029 #[test]
1030 fn test_find_lifetimes_function() {
1031 check(
1032 r#"
1033trait Foo<'a> {}
1034impl<'a> Foo<'a> for &'a () {}
1035fn foo<'a, 'b: 'a>(x: &'a<|> ()) -> &'a () where &'a (): Foo<'a> {
1036 fn bar<'a>(_: &'a ()) {}
1037 x
1038}
1039"#,
1040 expect![[r#"
1041 'a LIFETIME_PARAM FileId(0) 55..57 55..57 Lifetime
1042
1043 FileId(0) 63..65 Lifetime
1044 FileId(0) 71..73 Lifetime
1045 FileId(0) 82..84 Lifetime
1046 FileId(0) 95..97 Lifetime
1047 FileId(0) 106..108 Lifetime
1048 "#]],
1049 );
1050 }
1051
1052 #[test]
1053 fn test_find_lifetimes_type_alias() {
1054 check(
1055 r#"
1056type Foo<'a, T> where T: 'a<|> = &'a T;
1057"#,
1058 expect![[r#"
1059 'a LIFETIME_PARAM FileId(0) 9..11 9..11 Lifetime
1060
1061 FileId(0) 25..27 Lifetime
1062 FileId(0) 31..33 Lifetime
1063 "#]],
1064 );
1065 }
1066
1067 #[test]
1068 fn test_find_lifetimes_trait_impl() {
1069 check(
1070 r#"
1071trait Foo<'a> {
1072 fn foo() -> &'a ();
1073}
1074impl<'a> Foo<'a> for &'a () {
1075 fn foo() -> &'a<|> () {
1076 unimplemented!()
1077 }
1078}
1079"#,
1080 expect![[r#"
1081 'a LIFETIME_PARAM FileId(0) 47..49 47..49 Lifetime
1082
1083 FileId(0) 55..57 Lifetime
1084 FileId(0) 64..66 Lifetime
1085 FileId(0) 89..91 Lifetime
1086 "#]],
1087 );
1088 }
1008} 1089}
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs
index 44081f210..56e923841 100644
--- a/crates/ide/src/references/rename.rs
+++ b/crates/ide/src/references/rename.rs
@@ -35,6 +35,29 @@ impl fmt::Display for RenameError {
35 35
36impl Error for RenameError {} 36impl Error for RenameError {}
37 37
38pub(crate) fn prepare_rename(
39 db: &RootDatabase,
40 position: FilePosition,
41) -> Result<RangeInfo<()>, RenameError> {
42 let sema = Semantics::new(db);
43 let source_file = sema.parse(position.file_id);
44 let syntax = source_file.syntax();
45 if let Some(module) = find_module_at_offset(&sema, position, syntax) {
46 rename_mod(&sema, position, module, "dummy")
47 } else if let Some(self_token) =
48 syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW)
49 {
50 rename_self_to_param(&sema, position, self_token, "dummy")
51 } else {
52 let range = match find_all_refs(&sema, position, None) {
53 Some(RangeInfo { range, .. }) => range,
54 None => return Err(RenameError("No references found at position".to_string())),
55 };
56 Ok(RangeInfo::new(range, SourceChange::from(vec![])))
57 }
58 .map(|info| RangeInfo::new(info.range, ()))
59}
60
38pub(crate) fn rename( 61pub(crate) fn rename(
39 db: &RootDatabase, 62 db: &RootDatabase,
40 position: FilePosition, 63 position: FilePosition,
@@ -49,11 +72,18 @@ pub(crate) fn rename_with_semantics(
49 position: FilePosition, 72 position: FilePosition,
50 new_name: &str, 73 new_name: &str,
51) -> Result<RangeInfo<SourceChange>, RenameError> { 74) -> Result<RangeInfo<SourceChange>, RenameError> {
52 match lex_single_syntax_kind(new_name) { 75 let is_lifetime_name = match lex_single_syntax_kind(new_name) {
53 Some(res) => match res { 76 Some(res) => match res {
54 (SyntaxKind::IDENT, _) => (), 77 (SyntaxKind::IDENT, _) => false,
55 (SyntaxKind::UNDERSCORE, _) => (), 78 (SyntaxKind::UNDERSCORE, _) => false,
56 (SyntaxKind::SELF_KW, _) => return rename_to_self(&sema, position), 79 (SyntaxKind::SELF_KW, _) => return rename_to_self(&sema, position),
80 (SyntaxKind::LIFETIME_IDENT, _) if new_name != "'static" && new_name != "'_" => true,
81 (SyntaxKind::LIFETIME_IDENT, _) => {
82 return Err(RenameError(format!(
83 "Invalid name `{0}`: Cannot rename lifetime to {0}",
84 new_name
85 )))
86 }
57 (_, Some(syntax_error)) => { 87 (_, Some(syntax_error)) => {
58 return Err(RenameError(format!("Invalid name `{}`: {}", new_name, syntax_error))) 88 return Err(RenameError(format!("Invalid name `{}`: {}", new_name, syntax_error)))
59 } 89 }
@@ -62,18 +92,21 @@ pub(crate) fn rename_with_semantics(
62 } 92 }
63 }, 93 },
64 None => return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name))), 94 None => return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name))),
65 } 95 };
66 96
67 let source_file = sema.parse(position.file_id); 97 let source_file = sema.parse(position.file_id);
68 let syntax = source_file.syntax(); 98 let syntax = source_file.syntax();
69 if let Some(module) = find_module_at_offset(&sema, position, syntax) { 99 // this is here to prevent lifetime renames from happening on modules and self
100 if is_lifetime_name {
101 rename_reference(&sema, position, new_name, is_lifetime_name)
102 } else if let Some(module) = find_module_at_offset(&sema, position, syntax) {
70 rename_mod(&sema, position, module, new_name) 103 rename_mod(&sema, position, module, new_name)
71 } else if let Some(self_token) = 104 } else if let Some(self_token) =
72 syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW) 105 syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW)
73 { 106 {
74 rename_self_to_param(&sema, position, self_token, new_name) 107 rename_self_to_param(&sema, position, self_token, new_name)
75 } else { 108 } else {
76 rename_reference(&sema, position, new_name) 109 rename_reference(&sema, position, new_name, is_lifetime_name)
77 } 110 }
78} 111}
79 112
@@ -355,12 +388,26 @@ fn rename_reference(
355 sema: &Semantics<RootDatabase>, 388 sema: &Semantics<RootDatabase>,
356 position: FilePosition, 389 position: FilePosition,
357 new_name: &str, 390 new_name: &str,
391 is_lifetime_name: bool,
358) -> Result<RangeInfo<SourceChange>, RenameError> { 392) -> Result<RangeInfo<SourceChange>, RenameError> {
359 let RangeInfo { range, info: refs } = match find_all_refs(sema, position, None) { 393 let RangeInfo { range, info: refs } = match find_all_refs(sema, position, None) {
360 Some(range_info) => range_info, 394 Some(range_info) => range_info,
361 None => return Err(RenameError("No references found at position".to_string())), 395 None => return Err(RenameError("No references found at position".to_string())),
362 }; 396 };
363 397
398 match (refs.declaration.kind == ReferenceKind::Lifetime, is_lifetime_name) {
399 (true, false) => {
400 return Err(RenameError(format!(
401 "Invalid name `{}`: not a lifetime identifier",
402 new_name
403 )))
404 }
405 (false, true) => {
406 return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name)))
407 }
408 _ => (),
409 }
410
364 let edit = refs 411 let edit = refs
365 .into_iter() 412 .into_iter()
366 .map(|reference| source_edit_from_reference(sema, reference, new_name)) 413 .map(|reference| source_edit_from_reference(sema, reference, new_name))
@@ -465,6 +512,24 @@ mod tests {
465 } 512 }
466 513
467 #[test] 514 #[test]
515 fn test_rename_to_invalid_identifier_lifetime() {
516 check(
517 "'foo",
518 r#"fn main() { let i<|> = 1; }"#,
519 "error: Invalid name `'foo`: not an identifier",
520 );
521 }
522
523 #[test]
524 fn test_rename_to_invalid_identifier_lifetime2() {
525 check(
526 "foo",
527 r#"fn main<'a>(_: &'a<|> ()) {}"#,
528 "error: Invalid name `foo`: not a lifetime identifier",
529 );
530 }
531
532 #[test]
468 fn test_rename_for_local() { 533 fn test_rename_for_local() {
469 check( 534 check(
470 "k", 535 "k",
@@ -1396,4 +1461,31 @@ fn foo(Foo { i: bar }: foo) -> i32 {
1396"#, 1461"#,
1397 ) 1462 )
1398 } 1463 }
1464
1465 #[test]
1466 fn test_rename_lifetimes() {
1467 check(
1468 "'yeeee",
1469 r#"
1470trait Foo<'a> {
1471 fn foo() -> &'a ();
1472}
1473impl<'a> Foo<'a> for &'a () {
1474 fn foo() -> &'a<|> () {
1475 unimplemented!()
1476 }
1477}
1478"#,
1479 r#"
1480trait Foo<'a> {
1481 fn foo() -> &'a ();
1482}
1483impl<'yeeee> Foo<'yeeee> for &'yeeee () {
1484 fn foo() -> &'yeeee () {
1485 unimplemented!()
1486 }
1487}
1488"#,
1489 )
1490 }
1399} 1491}
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 646f63704..2f465c195 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -2,7 +2,7 @@ use std::fmt;
2 2
3use assists::utils::test_related_attribute; 3use assists::utils::test_related_attribute;
4use cfg::CfgExpr; 4use cfg::CfgExpr;
5use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics}; 5use hir::{AsAssocItem, HasAttrs, InFile, Semantics};
6use ide_db::RootDatabase; 6use ide_db::RootDatabase;
7use itertools::Itertools; 7use itertools::Itertools;
8use syntax::{ 8use syntax::{
@@ -10,7 +10,10 @@ use syntax::{
10 match_ast, SyntaxNode, 10 match_ast, SyntaxNode,
11}; 11};
12 12
13use crate::{display::ToNav, FileId, NavigationTarget}; 13use crate::{
14 display::{ToNav, TryToNav},
15 FileId, NavigationTarget,
16};
14 17
15#[derive(Debug, Clone)] 18#[derive(Debug, Clone)]
16pub struct Runnable { 19pub struct Runnable {
@@ -101,124 +104,109 @@ pub(crate) fn runnable(
101 item: SyntaxNode, 104 item: SyntaxNode,
102 file_id: FileId, 105 file_id: FileId,
103) -> Option<Runnable> { 106) -> Option<Runnable> {
104 match_ast! { 107 let runnable_item = match_ast! {
105 match item { 108 match (item.clone()) {
106 ast::Struct(it) => runnable_struct(sema, it, file_id),
107 ast::Fn(it) => runnable_fn(sema, it, file_id), 109 ast::Fn(it) => runnable_fn(sema, it, file_id),
108 ast::Module(it) => runnable_mod(sema, it, file_id), 110 ast::Module(it) => runnable_mod(sema, it),
109 _ => None, 111 _ => None,
110 } 112 }
111 } 113 };
114 runnable_item.or_else(|| runnable_doctest(sema, item))
112} 115}
113 116
114fn runnable_fn( 117fn runnable_fn(sema: &Semantics<RootDatabase>, func: ast::Fn, file_id: FileId) -> Option<Runnable> {
115 sema: &Semantics<RootDatabase>, 118 let def = sema.to_def(&func)?;
116 fn_def: ast::Fn, 119 let name_string = func.name()?.text().to_string();
117 file_id: FileId,
118) -> Option<Runnable> {
119 let name_string = fn_def.name()?.text().to_string();
120 120
121 let attrs = Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &fn_def));
122 let kind = if name_string == "main" { 121 let kind = if name_string == "main" {
123 RunnableKind::Bin 122 RunnableKind::Bin
124 } else { 123 } else {
125 let test_id = match sema.to_def(&fn_def).map(|def| def.module(sema.db)) { 124 let canonical_path = sema.to_def(&func).and_then(|def| {
126 Some(module) => { 125 let def: hir::ModuleDef = def.into();
127 let def = sema.to_def(&fn_def)?; 126 def.canonical_path(sema.db)
128 let impl_trait_name = def.as_assoc_item(sema.db).and_then(|assoc_item| { 127 });
129 match assoc_item.container(sema.db) { 128 let test_id = canonical_path.map(TestId::Path).unwrap_or(TestId::Name(name_string));
130 hir::AssocItemContainer::Trait(trait_item) => { 129
131 Some(trait_item.name(sema.db).to_string()) 130 if test_related_attribute(&func).is_some() {
132 } 131 let attr = TestAttr::from_fn(&func);
133 hir::AssocItemContainer::ImplDef(impl_def) => impl_def
134 .target_ty(sema.db)
135 .as_adt()
136 .map(|adt| adt.name(sema.db).to_string()),
137 }
138 });
139
140 let path_iter = module
141 .path_to_root(sema.db)
142 .into_iter()
143 .rev()
144 .filter_map(|it| it.name(sema.db))
145 .map(|name| name.to_string());
146
147 let path = if let Some(impl_trait_name) = impl_trait_name {
148 path_iter
149 .chain(std::iter::once(impl_trait_name))
150 .chain(std::iter::once(name_string))
151 .join("::")
152 } else {
153 path_iter.chain(std::iter::once(name_string)).join("::")
154 };
155
156 TestId::Path(path)
157 }
158 None => TestId::Name(name_string),
159 };
160
161 if test_related_attribute(&fn_def).is_some() {
162 let attr = TestAttr::from_fn(&fn_def);
163 RunnableKind::Test { test_id, attr } 132 RunnableKind::Test { test_id, attr }
164 } else if fn_def.has_atom_attr("bench") { 133 } else if func.has_atom_attr("bench") {
165 RunnableKind::Bench { test_id } 134 RunnableKind::Bench { test_id }
166 } else if has_runnable_doc_test(&attrs) {
167 RunnableKind::DocTest { test_id }
168 } else { 135 } else {
169 return None; 136 return None;
170 } 137 }
171 }; 138 };
172 139
173 let cfg = attrs.cfg(); 140 let nav = NavigationTarget::from_named(sema.db, InFile::new(file_id.into(), &func));
174 141 let cfg = def.attrs(sema.db).cfg();
175 let nav = if let RunnableKind::DocTest { .. } = kind {
176 NavigationTarget::from_doc_commented(
177 sema.db,
178 InFile::new(file_id.into(), &fn_def),
179 InFile::new(file_id.into(), &fn_def),
180 )
181 } else {
182 NavigationTarget::from_named(sema.db, InFile::new(file_id.into(), &fn_def))
183 };
184 Some(Runnable { nav, kind, cfg }) 142 Some(Runnable { nav, kind, cfg })
185} 143}
186 144
187fn runnable_struct( 145fn runnable_doctest(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> {
188 sema: &Semantics<RootDatabase>, 146 match_ast! {
189 struct_def: ast::Struct, 147 match item {
190 file_id: FileId, 148 ast::Fn(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
191) -> Option<Runnable> { 149 ast::Struct(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
192 let name_string = struct_def.name()?.text().to_string(); 150 ast::Enum(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
151 ast::Union(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
152 ast::Trait(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
153 ast::Const(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
154 ast::Static(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
155 ast::TypeAlias(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
156 _ => None,
157 }
158 }
159}
193 160
194 let attrs = 161fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Option<Runnable> {
195 Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &struct_def)); 162 let attrs = match def {
163 hir::ModuleDef::Module(it) => it.attrs(sema.db),
164 hir::ModuleDef::Function(it) => it.attrs(sema.db),
165 hir::ModuleDef::Adt(it) => it.attrs(sema.db),
166 hir::ModuleDef::EnumVariant(it) => it.attrs(sema.db),
167 hir::ModuleDef::Const(it) => it.attrs(sema.db),
168 hir::ModuleDef::Static(it) => it.attrs(sema.db),
169 hir::ModuleDef::Trait(it) => it.attrs(sema.db),
170 hir::ModuleDef::TypeAlias(it) => it.attrs(sema.db),
171 hir::ModuleDef::BuiltinType(_) => return None,
172 };
196 if !has_runnable_doc_test(&attrs) { 173 if !has_runnable_doc_test(&attrs) {
197 return None; 174 return None;
198 } 175 }
199 let cfg = attrs.cfg(); 176 let def_name = def.name(sema.db).map(|it| it.to_string());
200 177 let test_id = def
201 let test_id = match sema.to_def(&struct_def).map(|def| def.module(sema.db)) { 178 .canonical_path(sema.db)
202 Some(module) => { 179 // This probably belongs to canonical path?
203 let path_iter = module 180 .map(|path| {
204 .path_to_root(sema.db) 181 let assoc_def = match def {
205 .into_iter() 182 hir::ModuleDef::Function(it) => it.as_assoc_item(sema.db),
206 .rev() 183 hir::ModuleDef::Const(it) => it.as_assoc_item(sema.db),
207 .filter_map(|it| it.name(sema.db)) 184 hir::ModuleDef::TypeAlias(it) => it.as_assoc_item(sema.db),
208 .map(|name| name.to_string()); 185 _ => None,
209 let path = path_iter.chain(std::iter::once(name_string)).join("::"); 186 };
210 187 // FIXME: this also looks very wrong
211 TestId::Path(path) 188 if let Some(assoc_def) = assoc_def {
212 } 189 if let hir::AssocItemContainer::Impl(imp) = assoc_def.container(sema.db) {
213 None => TestId::Name(name_string), 190 if let Some(adt) = imp.target_ty(sema.db).as_adt() {
214 }; 191 let name = adt.name(sema.db).to_string();
215 192 let idx = path.rfind(':').unwrap_or(0);
216 let nav = NavigationTarget::from_doc_commented( 193 let (prefix, suffix) = path.split_at(idx);
217 sema.db, 194 return format!("{}{}::{}", prefix, name, suffix);
218 InFile::new(file_id.into(), &struct_def), 195 }
219 InFile::new(file_id.into(), &struct_def), 196 }
220 ); 197 }
221 Some(Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg }) 198 path
199 })
200 .map(TestId::Path)
201 .or_else(|| def_name.clone().map(TestId::Name))?;
202
203 let mut nav = def.try_to_nav(sema.db)?;
204 nav.focus_range = None;
205 nav.description = None;
206 nav.docs = None;
207 nav.kind = syntax::SyntaxKind::COMMENT;
208 let res = Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg: attrs.cfg() };
209 Some(res)
222} 210}
223 211
224#[derive(Debug, Copy, Clone)] 212#[derive(Debug, Copy, Clone)]
@@ -262,11 +250,7 @@ fn has_runnable_doc_test(attrs: &hir::Attrs) -> bool {
262 }) 250 })
263} 251}
264 252
265fn runnable_mod( 253fn runnable_mod(sema: &Semantics<RootDatabase>, module: ast::Module) -> Option<Runnable> {
266 sema: &Semantics<RootDatabase>,
267 module: ast::Module,
268 file_id: FileId,
269) -> Option<Runnable> {
270 if !has_test_function_or_multiple_test_submodules(&module) { 254 if !has_test_function_or_multiple_test_submodules(&module) {
271 return None; 255 return None;
272 } 256 }
@@ -279,7 +263,8 @@ fn runnable_mod(
279 .filter_map(|it| it.name(sema.db)) 263 .filter_map(|it| it.name(sema.db))
280 .join("::"); 264 .join("::");
281 265
282 let attrs = Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &module)); 266 let def = sema.to_def(&module)?;
267 let attrs = def.attrs(sema.db);
283 let cfg = attrs.cfg(); 268 let cfg = attrs.cfg();
284 let nav = module_def.to_nav(sema.db); 269 let nav = module_def.to_nav(sema.db);
285 Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) 270 Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg })
@@ -319,7 +304,7 @@ mod tests {
319 304
320 use crate::fixture; 305 use crate::fixture;
321 306
322 use super::{RunnableAction, BENCH, BIN, DOCTEST, TEST}; 307 use super::*;
323 308
324 fn check( 309 fn check(
325 ra_fixture: &str, 310 ra_fixture: &str,
@@ -548,7 +533,7 @@ struct StructWithRunnable(String);
548 full_range: 15..74, 533 full_range: 15..74,
549 focus_range: None, 534 focus_range: None,
550 name: "should_have_runnable", 535 name: "should_have_runnable",
551 kind: FN, 536 kind: COMMENT,
552 container_name: None, 537 container_name: None,
553 description: None, 538 description: None,
554 docs: None, 539 docs: None,
@@ -568,7 +553,7 @@ struct StructWithRunnable(String);
568 full_range: 76..148, 553 full_range: 76..148,
569 focus_range: None, 554 focus_range: None,
570 name: "should_have_runnable_1", 555 name: "should_have_runnable_1",
571 kind: FN, 556 kind: COMMENT,
572 container_name: None, 557 container_name: None,
573 description: None, 558 description: None,
574 docs: None, 559 docs: None,
@@ -588,7 +573,7 @@ struct StructWithRunnable(String);
588 full_range: 150..254, 573 full_range: 150..254,
589 focus_range: None, 574 focus_range: None,
590 name: "should_have_runnable_2", 575 name: "should_have_runnable_2",
591 kind: FN, 576 kind: COMMENT,
592 container_name: None, 577 container_name: None,
593 description: None, 578 description: None,
594 docs: None, 579 docs: None,
@@ -608,7 +593,7 @@ struct StructWithRunnable(String);
608 full_range: 756..821, 593 full_range: 756..821,
609 focus_range: None, 594 focus_range: None,
610 name: "StructWithRunnable", 595 name: "StructWithRunnable",
611 kind: STRUCT, 596 kind: COMMENT,
612 container_name: None, 597 container_name: None,
613 description: None, 598 description: None,
614 docs: None, 599 docs: None,
@@ -670,7 +655,7 @@ impl Data {
670 full_range: 44..98, 655 full_range: 44..98,
671 focus_range: None, 656 focus_range: None,
672 name: "foo", 657 name: "foo",
673 kind: FN, 658 kind: COMMENT,
674 container_name: None, 659 container_name: None,
675 description: None, 660 description: None,
676 docs: None, 661 docs: None,
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 990b0f7d9..488969f1a 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -806,6 +806,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
806 } 806 }
807 return h; 807 return h;
808 } 808 }
809 Definition::LifetimeParam(_) => HighlightTag::Lifetime,
809 } 810 }
810 .into() 811 .into()
811} 812}
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
index 0569cf1e5..3530a5fdb 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
@@ -38,6 +38,9 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
38<pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="punctuation">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="punctuation">}</span><span class="punctuation">;</span> 38<pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="punctuation">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="punctuation">}</span><span class="punctuation">;</span>
39<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="punctuation">{</span><span class="punctuation">}</span> 39<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="punctuation">{</span><span class="punctuation">}</span>
40 40
41<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span>
42<span class="keyword">macro</span> <span class="unresolved_reference declaration">Copy</span> <span class="punctuation">{</span><span class="punctuation">}</span>
43
41<span class="comment">// Needed for function consuming vs normal</span> 44<span class="comment">// Needed for function consuming vs normal</span>
42<span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration">marker</span> <span class="punctuation">{</span> 45<span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration">marker</span> <span class="punctuation">{</span>
43 <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">lang</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"copy"</span><span class="attribute attribute">]</span> 46 <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">lang</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"copy"</span><span class="attribute attribute">]</span>
@@ -119,7 +122,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
119 <span class="value_param callable">f</span><span class="punctuation">(</span><span class="punctuation">)</span> 122 <span class="value_param callable">f</span><span class="punctuation">(</span><span class="punctuation">)</span>
120<span class="punctuation">}</span> 123<span class="punctuation">}</span>
121 124
122<span class="keyword">fn</span> <span class="function declaration">foobar</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="keyword">impl</span> <span class="unresolved_reference">Copy</span> <span class="punctuation">{</span><span class="punctuation">}</span> 125<span class="keyword">fn</span> <span class="function declaration">foobar</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="keyword">impl</span> <span class="macro">Copy</span> <span class="punctuation">{</span><span class="punctuation">}</span>
123 126
124<span class="keyword">fn</span> <span class="function declaration">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> 127<span class="keyword">fn</span> <span class="function declaration">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
125 <span class="keyword">let</span> <span class="variable declaration">bar</span> <span class="operator">=</span> <span class="function">foobar</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> 128 <span class="keyword">let</span> <span class="variable declaration">bar</span> <span class="operator">=</span> <span class="function">foobar</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index 1dc018a16..f53d2c3ba 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -12,6 +12,9 @@ fn test_highlighting() {
12use inner::{self as inner_mod}; 12use inner::{self as inner_mod};
13mod inner {} 13mod inner {}
14 14
15#[rustc_builtin_macro]
16macro Copy {}
17
15// Needed for function consuming vs normal 18// Needed for function consuming vs normal
16pub mod marker { 19pub mod marker {
17 #[lang = "copy"] 20 #[lang = "copy"]
diff --git a/crates/ide_db/src/apply_change.rs b/crates/ide_db/src/apply_change.rs
index e2251f2b7..71c19ed13 100644
--- a/crates/ide_db/src/apply_change.rs
+++ b/crates/ide_db/src/apply_change.rs
@@ -163,7 +163,6 @@ impl RootDatabase {
163 hir::db::ExprScopesQuery 163 hir::db::ExprScopesQuery
164 hir::db::GenericParamsQuery 164 hir::db::GenericParamsQuery
165 hir::db::AttrsQuery 165 hir::db::AttrsQuery
166 hir::db::ModuleLangItemsQuery
167 hir::db::CrateLangItemsQuery 166 hir::db::CrateLangItemsQuery
168 hir::db::LangItemQuery 167 hir::db::LangItemQuery
169 hir::db::ImportMapQuery 168 hir::db::ImportMapQuery
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs
index d4a774261..bd2afc887 100644
--- a/crates/ide_db/src/defs.rs
+++ b/crates/ide_db/src/defs.rs
@@ -6,12 +6,12 @@
6// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). 6// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06).
7 7
8use hir::{ 8use hir::{
9 db::HirDatabase, Crate, Field, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, 9 db::HirDatabase, Crate, Field, HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module,
10 Name, PathResolution, Semantics, TypeParam, Visibility, 10 ModuleDef, Name, PathResolution, Semantics, TypeParam, Visibility,
11}; 11};
12use syntax::{ 12use syntax::{
13 ast::{self, AstNode}, 13 ast::{self, AstNode},
14 match_ast, SyntaxNode, 14 match_ast, SyntaxKind, SyntaxNode,
15}; 15};
16 16
17use crate::RootDatabase; 17use crate::RootDatabase;
@@ -22,9 +22,11 @@ pub enum Definition {
22 Macro(MacroDef), 22 Macro(MacroDef),
23 Field(Field), 23 Field(Field),
24 ModuleDef(ModuleDef), 24 ModuleDef(ModuleDef),
25 SelfType(ImplDef), 25 SelfType(Impl),
26 Local(Local), 26 Local(Local),
27 TypeParam(TypeParam), 27 TypeParam(TypeParam),
28 LifetimeParam(LifetimeParam),
29 // FIXME: Label
28} 30}
29 31
30impl Definition { 32impl Definition {
@@ -36,6 +38,7 @@ impl Definition {
36 Definition::SelfType(it) => Some(it.module(db)), 38 Definition::SelfType(it) => Some(it.module(db)),
37 Definition::Local(it) => Some(it.module(db)), 39 Definition::Local(it) => Some(it.module(db)),
38 Definition::TypeParam(it) => Some(it.module(db)), 40 Definition::TypeParam(it) => Some(it.module(db)),
41 Definition::LifetimeParam(it) => Some(it.module(db)),
39 } 42 }
40 } 43 }
41 44
@@ -47,6 +50,7 @@ impl Definition {
47 Definition::SelfType(_) => None, 50 Definition::SelfType(_) => None,
48 Definition::Local(_) => None, 51 Definition::Local(_) => None,
49 Definition::TypeParam(_) => None, 52 Definition::TypeParam(_) => None,
53 Definition::LifetimeParam(_) => None,
50 } 54 }
51 } 55 }
52 56
@@ -72,6 +76,7 @@ impl Definition {
72 Definition::SelfType(_) => return None, 76 Definition::SelfType(_) => return None,
73 Definition::Local(it) => it.name(db)?, 77 Definition::Local(it) => it.name(db)?,
74 Definition::TypeParam(it) => it.name(db), 78 Definition::TypeParam(it) => it.name(db),
79 Definition::LifetimeParam(it) => it.name(db),
75 }; 80 };
76 Some(name) 81 Some(name)
77 } 82 }
@@ -229,6 +234,25 @@ impl NameClass {
229 } 234 }
230 } 235 }
231 } 236 }
237
238 pub fn classify_lifetime(
239 sema: &Semantics<RootDatabase>,
240 lifetime: &ast::Lifetime,
241 ) -> Option<NameClass> {
242 let _p = profile::span("classify_lifetime").detail(|| lifetime.to_string());
243 let parent = lifetime.syntax().parent()?;
244
245 match_ast! {
246 match parent {
247 ast::LifetimeParam(it) => {
248 let def = sema.to_def(&it)?;
249 Some(NameClass::Definition(Definition::LifetimeParam(def)))
250 },
251 ast::Label(_it) => None,
252 _ => None,
253 }
254 }
255 }
232} 256}
233 257
234#[derive(Debug)] 258#[derive(Debug)]
@@ -338,6 +362,35 @@ impl NameRefClass {
338 let resolved = sema.resolve_extern_crate(&extern_crate)?; 362 let resolved = sema.resolve_extern_crate(&extern_crate)?;
339 Some(NameRefClass::ExternCrate(resolved)) 363 Some(NameRefClass::ExternCrate(resolved))
340 } 364 }
365
366 pub fn classify_lifetime(
367 sema: &Semantics<RootDatabase>,
368 lifetime: &ast::Lifetime,
369 ) -> Option<NameRefClass> {
370 let _p = profile::span("classify_lifetime_ref").detail(|| lifetime.to_string());
371 let parent = lifetime.syntax().parent()?;
372 match parent.kind() {
373 SyntaxKind::LIFETIME_ARG
374 | SyntaxKind::SELF_PARAM
375 | SyntaxKind::TYPE_BOUND
376 | SyntaxKind::WHERE_PRED
377 | SyntaxKind::REF_TYPE => sema
378 .resolve_lifetime_param(lifetime)
379 .map(Definition::LifetimeParam)
380 .map(NameRefClass::Definition),
381 // lifetime bounds, as in the 'b in 'a: 'b aren't wrapped in TypeBound nodes so we gotta check
382 // if our lifetime is in a LifetimeParam without being the constrained lifetime
383 _ if ast::LifetimeParam::cast(parent).and_then(|param| param.lifetime()).as_ref()
384 != Some(lifetime) =>
385 {
386 sema.resolve_lifetime_param(lifetime)
387 .map(Definition::LifetimeParam)
388 .map(NameRefClass::Definition)
389 }
390 SyntaxKind::BREAK_EXPR | SyntaxKind::CONTINUE_EXPR => None,
391 _ => None,
392 }
393 }
341} 394}
342 395
343impl From<PathResolution> for Definition { 396impl From<PathResolution> for Definition {
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs
index 3936c7390..525c8a41f 100644
--- a/crates/ide_db/src/search.rs
+++ b/crates/ide_db/src/search.rs
@@ -33,6 +33,7 @@ pub enum ReferenceKind {
33 RecordFieldExprOrPat, 33 RecordFieldExprOrPat,
34 SelfKw, 34 SelfKw,
35 EnumLiteral, 35 EnumLiteral,
36 Lifetime,
36 Other, 37 Other,
37} 38}
38 39
@@ -129,6 +130,25 @@ impl Definition {
129 return SearchScope::new(res); 130 return SearchScope::new(res);
130 } 131 }
131 132
133 if let Definition::LifetimeParam(param) = self {
134 let range = match param.parent(db) {
135 hir::GenericDef::Function(it) => it.source(db).value.syntax().text_range(),
136 hir::GenericDef::Adt(it) => match it {
137 hir::Adt::Struct(it) => it.source(db).value.syntax().text_range(),
138 hir::Adt::Union(it) => it.source(db).value.syntax().text_range(),
139 hir::Adt::Enum(it) => it.source(db).value.syntax().text_range(),
140 },
141 hir::GenericDef::Trait(it) => it.source(db).value.syntax().text_range(),
142 hir::GenericDef::TypeAlias(it) => it.source(db).value.syntax().text_range(),
143 hir::GenericDef::Impl(it) => it.source(db).value.syntax().text_range(),
144 hir::GenericDef::EnumVariant(it) => it.source(db).value.syntax().text_range(),
145 hir::GenericDef::Const(it) => it.source(db).value.syntax().text_range(),
146 };
147 let mut res = FxHashMap::default();
148 res.insert(file_id, Some(range));
149 return SearchScope::new(res);
150 }
151
132 let vis = self.visibility(db); 152 let vis = self.visibility(db);
133 153
134 if let Some(Visibility::Module(module)) = vis.and_then(|it| it.into()) { 154 if let Some(Visibility::Module(module)) = vis.and_then(|it| it.into()) {
@@ -255,25 +275,42 @@ impl<'a> FindUsages<'a> {
255 continue; 275 continue;
256 } 276 }
257 277
258 match sema.find_node_at_offset_with_descend(&tree, offset) { 278 if let Some(name_ref) = sema.find_node_at_offset_with_descend(&tree, offset) {
259 Some(name_ref) => { 279 if self.found_name_ref(&name_ref, sink) {
260 if self.found_name_ref(&name_ref, sink) { 280 return;
261 return; 281 }
262 } 282 } else if let Some(name) = sema.find_node_at_offset_with_descend(&tree, offset) {
283 if self.found_name(&name, sink) {
284 return;
285 }
286 } else if let Some(lifetime) = sema.find_node_at_offset_with_descend(&tree, offset)
287 {
288 if self.found_lifetime(&lifetime, sink) {
289 return;
263 } 290 }
264 None => match sema.find_node_at_offset_with_descend(&tree, offset) {
265 Some(name) => {
266 if self.found_name(&name, sink) {
267 return;
268 }
269 }
270 None => {}
271 },
272 } 291 }
273 } 292 }
274 } 293 }
275 } 294 }
276 295
296 fn found_lifetime(
297 &self,
298 lifetime: &ast::Lifetime,
299 sink: &mut dyn FnMut(Reference) -> bool,
300 ) -> bool {
301 match NameRefClass::classify_lifetime(self.sema, lifetime) {
302 Some(NameRefClass::Definition(def)) if &def == self.def => {
303 let reference = Reference {
304 file_range: self.sema.original_range(lifetime.syntax()),
305 kind: ReferenceKind::Lifetime,
306 access: None,
307 };
308 sink(reference)
309 }
310 _ => false, // not a usage
311 }
312 }
313
277 fn found_name_ref( 314 fn found_name_ref(
278 &self, 315 &self,
279 name_ref: &ast::NameRef, 316 name_ref: &ast::NameRef,
diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs
index 121063aea..ca455fa03 100644
--- a/crates/ide_db/src/symbol_index.rs
+++ b/crates/ide_db/src/symbol_index.rs
@@ -209,8 +209,7 @@ pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec<Fil
209 query.search(&buf) 209 query.search(&buf)
210} 210}
211 211
212pub fn index_resolve(db: &RootDatabase, name_ref: &ast::NameRef) -> Vec<FileSymbol> { 212pub fn index_resolve(db: &RootDatabase, name: &SmolStr) -> Vec<FileSymbol> {
213 let name = name_ref.text();
214 let mut query = Query::new(name.to_string()); 213 let mut query = Query::new(name.to_string());
215 query.exact(); 214 query.exact();
216 query.limit(4); 215 query.limit(4);
diff --git a/crates/mbe/src/mbe_expander/matcher.rs b/crates/mbe/src/mbe_expander/matcher.rs
index 93ee77908..7aeef7be5 100644
--- a/crates/mbe/src/mbe_expander/matcher.rs
+++ b/crates/mbe/src/mbe_expander/matcher.rs
@@ -295,7 +295,7 @@ impl<'a> TtIter<'a> {
295 295
296 impl<'a> TreeSink for OffsetTokenSink<'a> { 296 impl<'a> TreeSink for OffsetTokenSink<'a> {
297 fn token(&mut self, kind: SyntaxKind, mut n_tokens: u8) { 297 fn token(&mut self, kind: SyntaxKind, mut n_tokens: u8) {
298 if kind == SyntaxKind::LIFETIME { 298 if kind == SyntaxKind::LIFETIME_IDENT {
299 n_tokens = 2; 299 n_tokens = 2;
300 } 300 }
301 for _ in 0..n_tokens { 301 for _ in 0..n_tokens {
diff --git a/crates/mbe/src/subtree_source.rs b/crates/mbe/src/subtree_source.rs
index ccc56c479..d10d4b70e 100644
--- a/crates/mbe/src/subtree_source.rs
+++ b/crates/mbe/src/subtree_source.rs
@@ -84,7 +84,11 @@ impl<'a> SubtreeTokenSource<'a> {
84 } 84 }
85 85
86 if let Some((curr, text)) = is_lifetime(cursor) { 86 if let Some((curr, text)) = is_lifetime(cursor) {
87 cached.push(Some(TtToken { kind: LIFETIME, is_joint_to_next: false, text })); 87 cached.push(Some(TtToken {
88 kind: LIFETIME_IDENT,
89 is_joint_to_next: false,
90 text,
91 }));
88 self.cached_cursor.set(curr); 92 self.cached_cursor.set(curr);
89 continue; 93 continue;
90 } 94 }
@@ -172,7 +176,7 @@ fn convert_ident(ident: &tt::Ident) -> TtToken {
172 let kind = match ident.text.as_ref() { 176 let kind = match ident.text.as_ref() {
173 "true" => T![true], 177 "true" => T![true],
174 "false" => T![false], 178 "false" => T![false],
175 i if i.starts_with('\'') => LIFETIME, 179 i if i.starts_with('\'') => LIFETIME_IDENT,
176 _ => SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT), 180 _ => SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT),
177 }; 181 };
178 182
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs
index d987b2500..265c0d63d 100644
--- a/crates/mbe/src/syntax_bridge.rs
+++ b/crates/mbe/src/syntax_bridge.rs
@@ -380,7 +380,7 @@ trait TokenConvertor {
380 IDENT => make_leaf!(Ident), 380 IDENT => make_leaf!(Ident),
381 k if k.is_keyword() => make_leaf!(Ident), 381 k if k.is_keyword() => make_leaf!(Ident),
382 k if k.is_literal() => make_leaf!(Literal), 382 k if k.is_literal() => make_leaf!(Literal),
383 LIFETIME => { 383 LIFETIME_IDENT => {
384 let char_unit = TextSize::of('\''); 384 let char_unit = TextSize::of('\'');
385 let r = TextRange::at(range.start(), char_unit); 385 let r = TextRange::at(range.start(), char_unit);
386 let apostrophe = tt::Leaf::from(tt::Punct { 386 let apostrophe = tt::Leaf::from(tt::Punct {
@@ -620,7 +620,7 @@ impl<'a> TreeSink for TtTreeSink<'a> {
620 self.cursor = self.cursor.bump_subtree(); 620 self.cursor = self.cursor.bump_subtree();
621 return; 621 return;
622 } 622 }
623 if kind == LIFETIME { 623 if kind == LIFETIME_IDENT {
624 n_tokens = 2; 624 n_tokens = 2;
625 } 625 }
626 626
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index 116b991a8..23039eba4 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -283,6 +283,13 @@ fn name_ref_or_index(p: &mut Parser) {
283 m.complete(p, NAME_REF); 283 m.complete(p, NAME_REF);
284} 284}
285 285
286fn lifetime(p: &mut Parser) {
287 assert!(p.at(LIFETIME_IDENT));
288 let m = p.start();
289 p.bump(LIFETIME_IDENT);
290 m.complete(p, LIFETIME);
291}
292
286fn error_block(p: &mut Parser, message: &str) { 293fn error_block(p: &mut Parser, message: &str) {
287 assert!(p.at(T!['{'])); 294 assert!(p.at(T!['{']));
288 let m = p.start(); 295 let m = p.start();
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs
index 31f42f161..18b63feb7 100644
--- a/crates/parser/src/grammar/expressions/atom.rs
+++ b/crates/parser/src/grammar/expressions/atom.rs
@@ -48,7 +48,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet =
48 T![try], 48 T![try],
49 T![loop], 49 T![loop],
50 T![for], 50 T![for],
51 LIFETIME, 51 LIFETIME_IDENT,
52 ])); 52 ]));
53 53
54const EXPR_RECOVERY_SET: TokenSet = TokenSet::new(&[LET_KW, R_DOLLAR]); 54const EXPR_RECOVERY_SET: TokenSet = TokenSet::new(&[LET_KW, R_DOLLAR]);
@@ -75,7 +75,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
75 T![for] => for_expr(p, None), 75 T![for] => for_expr(p, None),
76 T![while] => while_expr(p, None), 76 T![while] => while_expr(p, None),
77 T![try] => try_block_expr(p, None), 77 T![try] => try_block_expr(p, None),
78 LIFETIME if la == T![:] => { 78 LIFETIME_IDENT if la == T![:] => {
79 let m = p.start(); 79 let m = p.start();
80 label(p); 80 label(p);
81 match p.current() { 81 match p.current() {
@@ -275,9 +275,9 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
275// 'c: for x in () {} 275// 'c: for x in () {}
276// } 276// }
277fn label(p: &mut Parser) { 277fn label(p: &mut Parser) {
278 assert!(p.at(LIFETIME) && p.nth(1) == T![:]); 278 assert!(p.at(LIFETIME_IDENT) && p.nth(1) == T![:]);
279 let m = p.start(); 279 let m = p.start();
280 p.bump(LIFETIME); 280 lifetime(p);
281 p.bump_any(); 281 p.bump_any();
282 m.complete(p, LABEL); 282 m.complete(p, LABEL);
283} 283}
@@ -501,7 +501,9 @@ fn continue_expr(p: &mut Parser) -> CompletedMarker {
501 assert!(p.at(T![continue])); 501 assert!(p.at(T![continue]));
502 let m = p.start(); 502 let m = p.start();
503 p.bump(T![continue]); 503 p.bump(T![continue]);
504 p.eat(LIFETIME); 504 if p.at(LIFETIME_IDENT) {
505 lifetime(p);
506 }
505 m.complete(p, CONTINUE_EXPR) 507 m.complete(p, CONTINUE_EXPR)
506} 508}
507 509
@@ -518,7 +520,9 @@ fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
518 assert!(p.at(T![break])); 520 assert!(p.at(T![break]));
519 let m = p.start(); 521 let m = p.start();
520 p.bump(T![break]); 522 p.bump(T![break]);
521 p.eat(LIFETIME); 523 if p.at(LIFETIME_IDENT) {
524 lifetime(p);
525 }
522 // test break_ambiguity 526 // test break_ambiguity
523 // fn foo(){ 527 // fn foo(){
524 // if break {} 528 // if break {}
diff --git a/crates/parser/src/grammar/items/traits.rs b/crates/parser/src/grammar/items/traits.rs
index 8394020da..ab9a12b4d 100644
--- a/crates/parser/src/grammar/items/traits.rs
+++ b/crates/parser/src/grammar/items/traits.rs
@@ -98,10 +98,10 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool {
98 // `<` `>` - empty generic parameters 98 // `<` `>` - empty generic parameters
99 // `<` `#` - generic parameters with attributes 99 // `<` `#` - generic parameters with attributes
100 // `<` `const` - const generic parameters 100 // `<` `const` - const generic parameters
101 // `<` (LIFETIME|IDENT) `>` - single generic parameter 101 // `<` (LIFETIME_IDENT|IDENT) `>` - single generic parameter
102 // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list 102 // `<` (LIFETIME_IDENT|IDENT) `,` - first generic parameter in a list
103 // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds 103 // `<` (LIFETIME_IDENT|IDENT) `:` - generic parameter with bounds
104 // `<` (LIFETIME|IDENT) `=` - generic parameter with a default 104 // `<` (LIFETIME_IDENT|IDENT) `=` - generic parameter with a default
105 // The only truly ambiguous case is 105 // The only truly ambiguous case is
106 // `<` IDENT `>` `::` IDENT ... 106 // `<` IDENT `>` `::` IDENT ...
107 // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`) 107 // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
@@ -113,7 +113,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool {
113 if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == CONST_KW { 113 if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == CONST_KW {
114 return true; 114 return true;
115 } 115 }
116 (p.nth(1) == LIFETIME || p.nth(1) == IDENT) 116 (p.nth(1) == LIFETIME_IDENT || p.nth(1) == IDENT)
117 && (p.nth(2) == T![>] || p.nth(2) == T![,] || p.nth(2) == T![:] || p.nth(2) == T![=]) 117 && (p.nth(2) == T![>] || p.nth(2) == T![,] || p.nth(2) == T![:] || p.nth(2) == T![=])
118} 118}
119 119
diff --git a/crates/parser/src/grammar/params.rs b/crates/parser/src/grammar/params.rs
index a665ffc13..3ee4e4fca 100644
--- a/crates/parser/src/grammar/params.rs
+++ b/crates/parser/src/grammar/params.rs
@@ -169,15 +169,20 @@ fn opt_self_param(p: &mut Parser) {
169 let la1 = p.nth(1); 169 let la1 = p.nth(1);
170 let la2 = p.nth(2); 170 let la2 = p.nth(2);
171 let la3 = p.nth(3); 171 let la3 = p.nth(3);
172 let n_toks = match (p.current(), la1, la2, la3) { 172 let mut n_toks = match (p.current(), la1, la2, la3) {
173 (T![&], T![self], _, _) => 2, 173 (T![&], T![self], _, _) => 2,
174 (T![&], T![mut], T![self], _) => 3, 174 (T![&], T![mut], T![self], _) => 3,
175 (T![&], LIFETIME, T![self], _) => 3, 175 (T![&], LIFETIME_IDENT, T![self], _) => 3,
176 (T![&], LIFETIME, T![mut], T![self]) => 4, 176 (T![&], LIFETIME_IDENT, T![mut], T![self]) => 4,
177 _ => return, 177 _ => return,
178 }; 178 };
179 m = p.start(); 179 m = p.start();
180 for _ in 0..n_toks { 180 p.bump_any();
181 if p.at(LIFETIME_IDENT) {
182 lifetime(p);
183 n_toks -= 1;
184 }
185 for _ in 1..n_toks {
181 p.bump_any(); 186 p.bump_any();
182 } 187 }
183 } 188 }
diff --git a/crates/parser/src/grammar/type_args.rs b/crates/parser/src/grammar/type_args.rs
index f2d34a749..a013c49b9 100644
--- a/crates/parser/src/grammar/type_args.rs
+++ b/crates/parser/src/grammar/type_args.rs
@@ -30,8 +30,8 @@ pub(super) fn opt_generic_arg_list(p: &mut Parser, colon_colon_required: bool) {
30fn generic_arg(p: &mut Parser) { 30fn generic_arg(p: &mut Parser) {
31 let m = p.start(); 31 let m = p.start();
32 match p.current() { 32 match p.current() {
33 LIFETIME => { 33 LIFETIME_IDENT => {
34 p.bump(LIFETIME); 34 lifetime(p);
35 m.complete(p, LIFETIME_ARG); 35 m.complete(p, LIFETIME_ARG);
36 } 36 }
37 // test associated_type_bounds 37 // test associated_type_bounds
diff --git a/crates/parser/src/grammar/type_params.rs b/crates/parser/src/grammar/type_params.rs
index bc7d8d724..9c3f7c28a 100644
--- a/crates/parser/src/grammar/type_params.rs
+++ b/crates/parser/src/grammar/type_params.rs
@@ -23,7 +23,7 @@ fn generic_param_list(p: &mut Parser) {
23 attributes::outer_attrs(p); 23 attributes::outer_attrs(p);
24 24
25 match p.current() { 25 match p.current() {
26 LIFETIME => lifetime_param(p, m), 26 LIFETIME_IDENT => lifetime_param(p, m),
27 IDENT => type_param(p, m), 27 IDENT => type_param(p, m),
28 CONST_KW => const_param(p, m), 28 CONST_KW => const_param(p, m),
29 _ => { 29 _ => {
@@ -40,8 +40,8 @@ fn generic_param_list(p: &mut Parser) {
40} 40}
41 41
42fn lifetime_param(p: &mut Parser, m: Marker) { 42fn lifetime_param(p: &mut Parser, m: Marker) {
43 assert!(p.at(LIFETIME)); 43 assert!(p.at(LIFETIME_IDENT));
44 p.bump(LIFETIME); 44 lifetime(p);
45 if p.at(T![:]) { 45 if p.at(T![:]) {
46 lifetime_bounds(p); 46 lifetime_bounds(p);
47 } 47 }
@@ -84,8 +84,8 @@ pub(super) fn bounds(p: &mut Parser) {
84fn lifetime_bounds(p: &mut Parser) { 84fn lifetime_bounds(p: &mut Parser) {
85 assert!(p.at(T![:])); 85 assert!(p.at(T![:]));
86 p.bump(T![:]); 86 p.bump(T![:]);
87 while p.at(LIFETIME) { 87 while p.at(LIFETIME_IDENT) {
88 p.bump(LIFETIME); 88 lifetime(p);
89 if !p.eat(T![+]) { 89 if !p.eat(T![+]) {
90 break; 90 break;
91 } 91 }
@@ -112,7 +112,7 @@ fn type_bound(p: &mut Parser) -> bool {
112 let has_paren = p.eat(T!['(']); 112 let has_paren = p.eat(T!['(']);
113 p.eat(T![?]); 113 p.eat(T![?]);
114 match p.current() { 114 match p.current() {
115 LIFETIME => p.bump(LIFETIME), 115 LIFETIME_IDENT => lifetime(p),
116 T![for] => types::for_type(p), 116 T![for] => types::for_type(p),
117 _ if paths::is_use_path_start(p) => types::path_type_(p, false), 117 _ if paths::is_use_path_start(p) => types::path_type_(p, false),
118 _ => { 118 _ => {
@@ -162,7 +162,7 @@ pub(super) fn opt_where_clause(p: &mut Parser) {
162 162
163fn is_where_predicate(p: &mut Parser) -> bool { 163fn is_where_predicate(p: &mut Parser) -> bool {
164 match p.current() { 164 match p.current() {
165 LIFETIME => true, 165 LIFETIME_IDENT => true,
166 T![impl] => false, 166 T![impl] => false,
167 token => types::TYPE_FIRST.contains(token), 167 token => types::TYPE_FIRST.contains(token),
168 } 168 }
@@ -175,8 +175,8 @@ fn is_where_clause_end(p: &mut Parser) -> bool {
175fn where_predicate(p: &mut Parser) { 175fn where_predicate(p: &mut Parser) {
176 let m = p.start(); 176 let m = p.start();
177 match p.current() { 177 match p.current() {
178 LIFETIME => { 178 LIFETIME_IDENT => {
179 p.bump(LIFETIME); 179 lifetime(p);
180 if p.at(T![:]) { 180 if p.at(T![:]) {
181 bounds(p); 181 bounds(p);
182 } else { 182 } else {
diff --git a/crates/parser/src/grammar/types.rs b/crates/parser/src/grammar/types.rs
index 1ea130ac5..36a15eace 100644
--- a/crates/parser/src/grammar/types.rs
+++ b/crates/parser/src/grammar/types.rs
@@ -167,7 +167,9 @@ fn ref_type(p: &mut Parser) {
167 assert!(p.at(T![&])); 167 assert!(p.at(T![&]));
168 let m = p.start(); 168 let m = p.start();
169 p.bump(T![&]); 169 p.bump(T![&]);
170 p.eat(LIFETIME); 170 if p.at(LIFETIME_IDENT) {
171 lifetime(p);
172 }
171 p.eat(T![mut]); 173 p.eat(T![mut]);
172 type_no_bounds(p); 174 type_no_bounds(p);
173 m.complete(p, REF_TYPE); 175 m.complete(p, REF_TYPE);
diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs
index 5d6ec17a4..980aa5979 100644
--- a/crates/parser/src/syntax_kind/generated.rs
+++ b/crates/parser/src/syntax_kind/generated.rs
@@ -116,7 +116,7 @@ pub enum SyntaxKind {
116 ERROR, 116 ERROR,
117 IDENT, 117 IDENT,
118 WHITESPACE, 118 WHITESPACE,
119 LIFETIME, 119 LIFETIME_IDENT,
120 COMMENT, 120 COMMENT,
121 SHEBANG, 121 SHEBANG,
122 L_DOLLAR, 122 L_DOLLAR,
@@ -237,6 +237,7 @@ pub enum SyntaxKind {
237 TYPE_PARAM, 237 TYPE_PARAM,
238 CONST_PARAM, 238 CONST_PARAM,
239 GENERIC_ARG_LIST, 239 GENERIC_ARG_LIST,
240 LIFETIME,
240 LIFETIME_ARG, 241 LIFETIME_ARG,
241 TYPE_ARG, 242 TYPE_ARG,
242 ASSOC_TYPE_ARG, 243 ASSOC_TYPE_ARG,
@@ -364,4 +365,4 @@ impl SyntaxKind {
364 } 365 }
365} 366}
366#[macro_export] 367#[macro_export]
367macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [lifetime] => { $ crate :: SyntaxKind :: LIFETIME } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } 368macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; }
diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs
index 894c5c952..bb3b6f2ef 100644
--- a/crates/project_model/src/cargo_workspace.rs
+++ b/crates/project_model/src/cargo_workspace.rs
@@ -16,6 +16,7 @@ use paths::{AbsPath, AbsPathBuf};
16use rustc_hash::FxHashMap; 16use rustc_hash::FxHashMap;
17 17
18use crate::cfg_flag::CfgFlag; 18use crate::cfg_flag::CfgFlag;
19use crate::utf8_stdout;
19 20
20/// `CargoWorkspace` represents the logical structure of, well, a Cargo 21/// `CargoWorkspace` represents the logical structure of, well, a Cargo
21/// workspace. It pretty closely mirrors `cargo metadata` output. 22/// workspace. It pretty closely mirrors `cargo metadata` output.
@@ -166,8 +167,34 @@ impl CargoWorkspace {
166 if let Some(parent) = cargo_toml.parent() { 167 if let Some(parent) = cargo_toml.parent() {
167 meta.current_dir(parent.to_path_buf()); 168 meta.current_dir(parent.to_path_buf());
168 } 169 }
169 if let Some(target) = config.target.as_ref() { 170 let target = if let Some(target) = config.target.as_ref() {
170 meta.other_options(vec![String::from("--filter-platform"), target.clone()]); 171 Some(target.clone())
172 } else {
173 // cargo metadata defaults to giving information for _all_ targets.
174 // In the absence of a preference from the user, we use the host platform.
175 let mut rustc = Command::new(toolchain::rustc());
176 rustc.current_dir(cargo_toml.parent().unwrap()).arg("-vV");
177 log::debug!("Discovering host platform by {:?}", rustc);
178 match utf8_stdout(rustc) {
179 Ok(stdout) => {
180 let field = "host: ";
181 let target = stdout.lines().find_map(|l| l.strip_prefix(field));
182 if let Some(target) = target {
183 Some(target.to_string())
184 } else {
185 // If we fail to resolve the host platform, it's not the end of the world.
186 log::info!("rustc -vV did not report host platform, got:\n{}", stdout);
187 None
188 }
189 }
190 Err(e) => {
191 log::warn!("Failed to discover host platform: {}", e);
192 None
193 }
194 }
195 };
196 if let Some(target) = target {
197 meta.other_options(vec![String::from("--filter-platform"), target]);
171 } 198 }
172 let mut meta = meta.exec().with_context(|| { 199 let mut meta = meta.exec().with_context(|| {
173 format!("Failed to run `cargo metadata --manifest-path {}`", cargo_toml.display()) 200 format!("Failed to run `cargo metadata --manifest-path {}`", cargo_toml.display())
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index 039976e4b..0b4d3f4eb 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -21,7 +21,7 @@ env_logger = { version = "0.8.1", default-features = false }
21itertools = "0.9.0" 21itertools = "0.9.0"
22jod-thread = "0.1.0" 22jod-thread = "0.1.0"
23log = "0.4.8" 23log = "0.4.8"
24lsp-types = { version = "0.85.0", features = ["proposed"] } 24lsp-types = { version = "0.86.0", features = ["proposed"] }
25parking_lot = "0.11.0" 25parking_lot = "0.11.0"
26pico-args = "0.3.1" 26pico-args = "0.3.1"
27oorandom = "11.1.2" 27oorandom = "11.1.2"
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index 5e4c22bc5..de5eb93b5 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -64,7 +64,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
64 prepare_provider: Some(true), 64 prepare_provider: Some(true),
65 work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, 65 work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
66 })), 66 })),
67 on_type_rename_provider: None, 67 linked_editing_range_provider: None,
68 document_link_provider: None, 68 document_link_provider: None,
69 color_provider: None, 69 color_provider: None,
70 execute_command_provider: None, 70 execute_command_provider: None,
@@ -83,6 +83,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
83 } 83 }
84 .into(), 84 .into(),
85 ), 85 ),
86 moniker_provider: None,
86 experimental: Some(json!({ 87 experimental: Some(json!({
87 "joinLines": true, 88 "joinLines": true,
88 "ssr": true, 89 "ssr": true,
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 94e2bfa1b..af226c109 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -733,7 +733,7 @@ pub(crate) fn handle_prepare_rename(
733 let _p = profile::span("handle_prepare_rename"); 733 let _p = profile::span("handle_prepare_rename");
734 let position = from_proto::file_position(&snap, params)?; 734 let position = from_proto::file_position(&snap, params)?;
735 735
736 let change = snap.analysis.rename(position, "dummy")??; 736 let change = snap.analysis.prepare_rename(position)??;
737 let line_index = snap.analysis.file_line_index(position.file_id)?; 737 let line_index = snap.analysis.file_line_index(position.file_id)?;
738 let range = to_proto::range(&line_index, change.range); 738 let range = to_proto::range(&line_index, change.range);
739 Ok(Some(PrepareRenameResponse::Range(range))) 739 Ok(Some(PrepareRenameResponse::Range(range)))
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 715f8927a..72f77a016 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -633,7 +633,7 @@ pub(crate) fn resource_op(
633 lsp_types::ResourceOp::Create(lsp_types::CreateFile { 633 lsp_types::ResourceOp::Create(lsp_types::CreateFile {
634 uri, 634 uri,
635 options: None, 635 options: None,
636 annotation: None, 636 annotation_id: None,
637 }) 637 })
638 } 638 }
639 FileSystemEdit::MoveFile { src, dst } => { 639 FileSystemEdit::MoveFile { src, dst } => {
@@ -643,7 +643,7 @@ pub(crate) fn resource_op(
643 old_uri, 643 old_uri,
644 new_uri, 644 new_uri,
645 options: None, 645 options: None,
646 annotation: None, 646 annotation_id: None,
647 }) 647 })
648 } 648 }
649 } 649 }
@@ -708,6 +708,7 @@ impl From<lsp_ext::SnippetWorkspaceEdit> for lsp_types::WorkspaceEdit {
708 .collect(), 708 .collect(),
709 ) 709 )
710 }), 710 }),
711 change_annotations: None,
711 } 712 }
712 } 713 }
713} 714}
diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs
index 7844f9ed6..83de067d9 100644
--- a/crates/syntax/src/ast.rs
+++ b/crates/syntax/src/ast.rs
@@ -19,8 +19,8 @@ pub use self::{
19 expr_ext::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp}, 19 expr_ext::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp},
20 generated::{nodes::*, tokens::*}, 20 generated::{nodes::*, tokens::*},
21 node_ext::{ 21 node_ext::{
22 AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents, 22 AttrKind, FieldKind, Macro, NameOrNameRef, PathSegmentKind, SelfParamKind,
23 StructKind, TypeBoundKind, VisibilityKind, 23 SlicePatComponents, StructKind, TypeBoundKind, VisibilityKind,
24 }, 24 },
25 token_ext::*, 25 token_ext::*,
26 traits::*, 26 traits::*,
@@ -311,7 +311,7 @@ where
311 let pred = predicates.next().unwrap(); 311 let pred = predicates.next().unwrap();
312 let mut bounds = pred.type_bound_list().unwrap().bounds(); 312 let mut bounds = pred.type_bound_list().unwrap().bounds();
313 313
314 assert_eq!("'a", pred.lifetime_token().unwrap().text()); 314 assert_eq!("'a", pred.lifetime().unwrap().lifetime_ident_token().unwrap().text());
315 315
316 assert_bound("'b", bounds.next()); 316 assert_bound("'b", bounds.next());
317 assert_bound("'c", bounds.next()); 317 assert_bound("'c", bounds.next());
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index 0ad75214f..1588ba93e 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -20,6 +20,15 @@ impl NameRef {
20 pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) } 20 pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) }
21} 21}
22#[derive(Debug, Clone, PartialEq, Eq, Hash)] 22#[derive(Debug, Clone, PartialEq, Eq, Hash)]
23pub struct Lifetime {
24 pub(crate) syntax: SyntaxNode,
25}
26impl Lifetime {
27 pub fn lifetime_ident_token(&self) -> Option<SyntaxToken> {
28 support::token(&self.syntax, T![lifetime_ident])
29 }
30}
31#[derive(Debug, Clone, PartialEq, Eq, Hash)]
23pub struct Path { 32pub struct Path {
24 pub(crate) syntax: SyntaxNode, 33 pub(crate) syntax: SyntaxNode,
25} 34}
@@ -105,9 +114,7 @@ pub struct LifetimeArg {
105 pub(crate) syntax: SyntaxNode, 114 pub(crate) syntax: SyntaxNode,
106} 115}
107impl LifetimeArg { 116impl LifetimeArg {
108 pub fn lifetime_token(&self) -> Option<SyntaxToken> { 117 pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
109 support::token(&self.syntax, T![lifetime])
110 }
111} 118}
112#[derive(Debug, Clone, PartialEq, Eq, Hash)] 119#[derive(Debug, Clone, PartialEq, Eq, Hash)]
113pub struct ConstArg { 120pub struct ConstArg {
@@ -286,6 +293,18 @@ impl MacroRules {
286 pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) } 293 pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
287} 294}
288#[derive(Debug, Clone, PartialEq, Eq, Hash)] 295#[derive(Debug, Clone, PartialEq, Eq, Hash)]
296pub struct MacroDef {
297 pub(crate) syntax: SyntaxNode,
298}
299impl ast::AttrsOwner for MacroDef {}
300impl ast::NameOwner for MacroDef {}
301impl ast::VisibilityOwner for MacroDef {}
302impl MacroDef {
303 pub fn macro_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![macro]) }
304 pub fn args(&self) -> Option<TokenTree> { support::child(&self.syntax) }
305 pub fn body(&self) -> Option<TokenTree> { support::child(&self.syntax) }
306}
307#[derive(Debug, Clone, PartialEq, Eq, Hash)]
289pub struct Module { 308pub struct Module {
290 pub(crate) syntax: SyntaxNode, 309 pub(crate) syntax: SyntaxNode,
291} 310}
@@ -475,9 +494,7 @@ pub struct SelfParam {
475impl ast::AttrsOwner for SelfParam {} 494impl ast::AttrsOwner for SelfParam {}
476impl SelfParam { 495impl SelfParam {
477 pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) } 496 pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
478 pub fn lifetime_token(&self) -> Option<SyntaxToken> { 497 pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
479 support::token(&self.syntax, T![lifetime])
480 }
481 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) } 498 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
482 pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) } 499 pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
483 pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) } 500 pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
@@ -593,9 +610,7 @@ pub struct LifetimeParam {
593impl ast::AttrsOwner for LifetimeParam {} 610impl ast::AttrsOwner for LifetimeParam {}
594impl ast::TypeBoundsOwner for LifetimeParam {} 611impl ast::TypeBoundsOwner for LifetimeParam {}
595impl LifetimeParam { 612impl LifetimeParam {
596 pub fn lifetime_token(&self) -> Option<SyntaxToken> { 613 pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
597 support::token(&self.syntax, T![lifetime])
598 }
599} 614}
600#[derive(Debug, Clone, PartialEq, Eq, Hash)] 615#[derive(Debug, Clone, PartialEq, Eq, Hash)]
601pub struct TypeParam { 616pub struct TypeParam {
@@ -616,9 +631,7 @@ impl ast::TypeBoundsOwner for WherePred {}
616impl WherePred { 631impl WherePred {
617 pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) } 632 pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
618 pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) } 633 pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
619 pub fn lifetime_token(&self) -> Option<SyntaxToken> { 634 pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
620 support::token(&self.syntax, T![lifetime])
621 }
622 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } 635 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
623} 636}
624#[derive(Debug, Clone, PartialEq, Eq, Hash)] 637#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -694,9 +707,7 @@ pub struct BreakExpr {
694impl ast::AttrsOwner for BreakExpr {} 707impl ast::AttrsOwner for BreakExpr {}
695impl BreakExpr { 708impl BreakExpr {
696 pub fn break_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![break]) } 709 pub fn break_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![break]) }
697 pub fn lifetime_token(&self) -> Option<SyntaxToken> { 710 pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
698 support::token(&self.syntax, T![lifetime])
699 }
700 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } 711 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
701} 712}
702#[derive(Debug, Clone, PartialEq, Eq, Hash)] 713#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -740,9 +751,7 @@ impl ContinueExpr {
740 pub fn continue_token(&self) -> Option<SyntaxToken> { 751 pub fn continue_token(&self) -> Option<SyntaxToken> {
741 support::token(&self.syntax, T![continue]) 752 support::token(&self.syntax, T![continue])
742 } 753 }
743 pub fn lifetime_token(&self) -> Option<SyntaxToken> { 754 pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
744 support::token(&self.syntax, T![lifetime])
745 }
746} 755}
747#[derive(Debug, Clone, PartialEq, Eq, Hash)] 756#[derive(Debug, Clone, PartialEq, Eq, Hash)]
748pub struct EffectExpr { 757pub struct EffectExpr {
@@ -925,9 +934,8 @@ pub struct Label {
925 pub(crate) syntax: SyntaxNode, 934 pub(crate) syntax: SyntaxNode,
926} 935}
927impl Label { 936impl Label {
928 pub fn lifetime_token(&self) -> Option<SyntaxToken> { 937 pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
929 support::token(&self.syntax, T![lifetime]) 938 pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
930 }
931} 939}
932#[derive(Debug, Clone, PartialEq, Eq, Hash)] 940#[derive(Debug, Clone, PartialEq, Eq, Hash)]
933pub struct RecordExprFieldList { 941pub struct RecordExprFieldList {
@@ -1088,9 +1096,7 @@ pub struct RefType {
1088} 1096}
1089impl RefType { 1097impl RefType {
1090 pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) } 1098 pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
1091 pub fn lifetime_token(&self) -> Option<SyntaxToken> { 1099 pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
1092 support::token(&self.syntax, T![lifetime])
1093 }
1094 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) } 1100 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
1095 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } 1101 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
1096} 1102}
@@ -1117,9 +1123,7 @@ pub struct TypeBound {
1117 pub(crate) syntax: SyntaxNode, 1123 pub(crate) syntax: SyntaxNode,
1118} 1124}
1119impl TypeBound { 1125impl TypeBound {
1120 pub fn lifetime_token(&self) -> Option<SyntaxToken> { 1126 pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
1121 support::token(&self.syntax, T![lifetime])
1122 }
1123 pub fn question_mark_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![?]) } 1127 pub fn question_mark_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![?]) }
1124 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } 1128 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
1125} 1129}
@@ -1332,6 +1336,7 @@ pub enum Item {
1332 Impl(Impl), 1336 Impl(Impl),
1333 MacroCall(MacroCall), 1337 MacroCall(MacroCall),
1334 MacroRules(MacroRules), 1338 MacroRules(MacroRules),
1339 MacroDef(MacroDef),
1335 Module(Module), 1340 Module(Module),
1336 Static(Static), 1341 Static(Static),
1337 Struct(Struct), 1342 Struct(Struct),
@@ -1425,6 +1430,17 @@ impl AstNode for NameRef {
1425 } 1430 }
1426 fn syntax(&self) -> &SyntaxNode { &self.syntax } 1431 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1427} 1432}
1433impl AstNode for Lifetime {
1434 fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME }
1435 fn cast(syntax: SyntaxNode) -> Option<Self> {
1436 if Self::can_cast(syntax.kind()) {
1437 Some(Self { syntax })
1438 } else {
1439 None
1440 }
1441 }
1442 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1443}
1428impl AstNode for Path { 1444impl AstNode for Path {
1429 fn can_cast(kind: SyntaxKind) -> bool { kind == PATH } 1445 fn can_cast(kind: SyntaxKind) -> bool { kind == PATH }
1430 fn cast(syntax: SyntaxNode) -> Option<Self> { 1446 fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -1689,6 +1705,17 @@ impl AstNode for MacroRules {
1689 } 1705 }
1690 fn syntax(&self) -> &SyntaxNode { &self.syntax } 1706 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1691} 1707}
1708impl AstNode for MacroDef {
1709 fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_DEF }
1710 fn cast(syntax: SyntaxNode) -> Option<Self> {
1711 if Self::can_cast(syntax.kind()) {
1712 Some(Self { syntax })
1713 } else {
1714 None
1715 }
1716 }
1717 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1718}
1692impl AstNode for Module { 1719impl AstNode for Module {
1693 fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE } 1720 fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE }
1694 fn cast(syntax: SyntaxNode) -> Option<Self> { 1721 fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3086,6 +3113,9 @@ impl From<MacroCall> for Item {
3086impl From<MacroRules> for Item { 3113impl From<MacroRules> for Item {
3087 fn from(node: MacroRules) -> Item { Item::MacroRules(node) } 3114 fn from(node: MacroRules) -> Item { Item::MacroRules(node) }
3088} 3115}
3116impl From<MacroDef> for Item {
3117 fn from(node: MacroDef) -> Item { Item::MacroDef(node) }
3118}
3089impl From<Module> for Item { 3119impl From<Module> for Item {
3090 fn from(node: Module) -> Item { Item::Module(node) } 3120 fn from(node: Module) -> Item { Item::Module(node) }
3091} 3121}
@@ -3111,7 +3141,7 @@ impl AstNode for Item {
3111 fn can_cast(kind: SyntaxKind) -> bool { 3141 fn can_cast(kind: SyntaxKind) -> bool {
3112 match kind { 3142 match kind {
3113 CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MACRO_RULES 3143 CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MACRO_RULES
3114 | MODULE | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true, 3144 | MACRO_DEF | MODULE | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true,
3115 _ => false, 3145 _ => false,
3116 } 3146 }
3117 } 3147 }
@@ -3125,6 +3155,7 @@ impl AstNode for Item {
3125 IMPL => Item::Impl(Impl { syntax }), 3155 IMPL => Item::Impl(Impl { syntax }),
3126 MACRO_CALL => Item::MacroCall(MacroCall { syntax }), 3156 MACRO_CALL => Item::MacroCall(MacroCall { syntax }),
3127 MACRO_RULES => Item::MacroRules(MacroRules { syntax }), 3157 MACRO_RULES => Item::MacroRules(MacroRules { syntax }),
3158 MACRO_DEF => Item::MacroDef(MacroDef { syntax }),
3128 MODULE => Item::Module(Module { syntax }), 3159 MODULE => Item::Module(Module { syntax }),
3129 STATIC => Item::Static(Static { syntax }), 3160 STATIC => Item::Static(Static { syntax }),
3130 STRUCT => Item::Struct(Struct { syntax }), 3161 STRUCT => Item::Struct(Struct { syntax }),
@@ -3146,6 +3177,7 @@ impl AstNode for Item {
3146 Item::Impl(it) => &it.syntax, 3177 Item::Impl(it) => &it.syntax,
3147 Item::MacroCall(it) => &it.syntax, 3178 Item::MacroCall(it) => &it.syntax,
3148 Item::MacroRules(it) => &it.syntax, 3179 Item::MacroRules(it) => &it.syntax,
3180 Item::MacroDef(it) => &it.syntax,
3149 Item::Module(it) => &it.syntax, 3181 Item::Module(it) => &it.syntax,
3150 Item::Static(it) => &it.syntax, 3182 Item::Static(it) => &it.syntax,
3151 Item::Struct(it) => &it.syntax, 3183 Item::Struct(it) => &it.syntax,
@@ -3495,6 +3527,11 @@ impl std::fmt::Display for NameRef {
3495 std::fmt::Display::fmt(self.syntax(), f) 3527 std::fmt::Display::fmt(self.syntax(), f)
3496 } 3528 }
3497} 3529}
3530impl std::fmt::Display for Lifetime {
3531 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3532 std::fmt::Display::fmt(self.syntax(), f)
3533 }
3534}
3498impl std::fmt::Display for Path { 3535impl std::fmt::Display for Path {
3499 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3536 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3500 std::fmt::Display::fmt(self.syntax(), f) 3537 std::fmt::Display::fmt(self.syntax(), f)
@@ -3615,6 +3652,11 @@ impl std::fmt::Display for MacroRules {
3615 std::fmt::Display::fmt(self.syntax(), f) 3652 std::fmt::Display::fmt(self.syntax(), f)
3616 } 3653 }
3617} 3654}
3655impl std::fmt::Display for MacroDef {
3656 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3657 std::fmt::Display::fmt(self.syntax(), f)
3658 }
3659}
3618impl std::fmt::Display for Module { 3660impl std::fmt::Display for Module {
3619 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3661 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3620 std::fmt::Display::fmt(self.syntax(), f) 3662 std::fmt::Display::fmt(self.syntax(), f)
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index c59a29eab..c45cb514a 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -3,6 +3,7 @@
3 3
4use std::fmt; 4use std::fmt;
5 5
6use ast::AttrsOwner;
6use itertools::Itertools; 7use itertools::Itertools;
7use parser::SyntaxKind; 8use parser::SyntaxKind;
8 9
@@ -11,6 +12,12 @@ use crate::{
11 SmolStr, SyntaxElement, SyntaxToken, T, 12 SmolStr, SyntaxElement, SyntaxToken, T,
12}; 13};
13 14
15impl ast::Lifetime {
16 pub fn text(&self) -> &SmolStr {
17 text_of_first_token(self.syntax())
18 }
19}
20
14impl ast::Name { 21impl ast::Name {
15 pub fn text(&self) -> &SmolStr { 22 pub fn text(&self) -> &SmolStr {
16 text_of_first_token(self.syntax()) 23 text_of_first_token(self.syntax())
@@ -31,6 +38,57 @@ fn text_of_first_token(node: &SyntaxNode) -> &SmolStr {
31 node.green().children().next().and_then(|it| it.into_token()).unwrap().text() 38 node.green().children().next().and_then(|it| it.into_token()).unwrap().text()
32} 39}
33 40
41pub enum Macro {
42 MacroRules(ast::MacroRules),
43 MacroDef(ast::MacroDef),
44}
45
46impl From<ast::MacroRules> for Macro {
47 fn from(it: ast::MacroRules) -> Self {
48 Macro::MacroRules(it)
49 }
50}
51
52impl From<ast::MacroDef> for Macro {
53 fn from(it: ast::MacroDef) -> Self {
54 Macro::MacroDef(it)
55 }
56}
57
58impl AstNode for Macro {
59 fn can_cast(kind: SyntaxKind) -> bool {
60 match kind {
61 SyntaxKind::MACRO_RULES | SyntaxKind::MACRO_DEF => true,
62 _ => false,
63 }
64 }
65 fn cast(syntax: SyntaxNode) -> Option<Self> {
66 let res = match syntax.kind() {
67 SyntaxKind::MACRO_RULES => Macro::MacroRules(ast::MacroRules { syntax }),
68 SyntaxKind::MACRO_DEF => Macro::MacroDef(ast::MacroDef { syntax }),
69 _ => return None,
70 };
71 Some(res)
72 }
73 fn syntax(&self) -> &SyntaxNode {
74 match self {
75 Macro::MacroRules(it) => it.syntax(),
76 Macro::MacroDef(it) => it.syntax(),
77 }
78 }
79}
80
81impl NameOwner for Macro {
82 fn name(&self) -> Option<ast::Name> {
83 match self {
84 Macro::MacroRules(mac) => mac.name(),
85 Macro::MacroDef(mac) => mac.name(),
86 }
87 }
88}
89
90impl AttrsOwner for Macro {}
91
34#[derive(Debug, Clone, PartialEq, Eq)] 92#[derive(Debug, Clone, PartialEq, Eq)]
35pub enum AttrKind { 93pub enum AttrKind {
36 Inner, 94 Inner,
@@ -341,7 +399,7 @@ pub enum TypeBoundKind {
341 /// for<'a> ... 399 /// for<'a> ...
342 ForType(ast::ForType), 400 ForType(ast::ForType),
343 /// 'a 401 /// 'a
344 Lifetime(SyntaxToken), 402 Lifetime(ast::Lifetime),
345} 403}
346 404
347impl ast::TypeBound { 405impl ast::TypeBound {
@@ -350,7 +408,7 @@ impl ast::TypeBound {
350 TypeBoundKind::PathType(path_type) 408 TypeBoundKind::PathType(path_type)
351 } else if let Some(for_type) = support::children(self.syntax()).next() { 409 } else if let Some(for_type) = support::children(self.syntax()).next() {
352 TypeBoundKind::ForType(for_type) 410 TypeBoundKind::ForType(for_type)
353 } else if let Some(lifetime) = self.lifetime_token() { 411 } else if let Some(lifetime) = self.lifetime() {
354 TypeBoundKind::Lifetime(lifetime) 412 TypeBoundKind::Lifetime(lifetime)
355 } else { 413 } else {
356 unreachable!() 414 unreachable!()
@@ -388,7 +446,7 @@ impl ast::LifetimeParam {
388 .children_with_tokens() 446 .children_with_tokens()
389 .filter_map(|it| it.into_token()) 447 .filter_map(|it| it.into_token())
390 .skip_while(|x| x.kind() != T![:]) 448 .skip_while(|x| x.kind() != T![:])
391 .filter(|it| it.kind() == T![lifetime]) 449 .filter(|it| it.kind() == T![lifetime_ident])
392 } 450 }
393} 451}
394 452
@@ -462,4 +520,6 @@ impl ast::DocCommentsOwner for ast::Const {}
462impl ast::DocCommentsOwner for ast::TypeAlias {} 520impl ast::DocCommentsOwner for ast::TypeAlias {}
463impl ast::DocCommentsOwner for ast::Impl {} 521impl ast::DocCommentsOwner for ast::Impl {}
464impl ast::DocCommentsOwner for ast::MacroRules {} 522impl ast::DocCommentsOwner for ast::MacroRules {}
523impl ast::DocCommentsOwner for ast::MacroDef {}
524impl ast::DocCommentsOwner for ast::Macro {}
465impl ast::DocCommentsOwner for ast::Use {} 525impl ast::DocCommentsOwner for ast::Use {}
diff --git a/crates/syntax/src/display.rs b/crates/syntax/src/display.rs
index d33bde30c..391647fc6 100644
--- a/crates/syntax/src/display.rs
+++ b/crates/syntax/src/display.rs
@@ -76,8 +76,20 @@ pub fn type_label(node: &ast::TypeAlias) -> String {
76 label.trim().to_owned() 76 label.trim().to_owned()
77} 77}
78 78
79pub fn macro_label(node: &ast::MacroRules) -> String { 79pub fn macro_label(node: &ast::Macro) -> String {
80 let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default(); 80 let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default();
81 let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" }; 81 match node {
82 format!("{}macro_rules! {}", vis, name) 82 ast::Macro::MacroRules(node) => {
83 let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" };
84 format!("{}macro_rules! {}", vis, name)
85 }
86 ast::Macro::MacroDef(node) => {
87 let mut s = String::new();
88 if let Some(vis) = node.visibility() {
89 format_to!(s, "{} ", vis);
90 }
91 format_to!(s, "macro {}", name);
92 s
93 }
94 }
83} 95}
diff --git a/crates/syntax/src/parsing/lexer.rs b/crates/syntax/src/parsing/lexer.rs
index 8afd7e53b..0cbba73c5 100644
--- a/crates/syntax/src/parsing/lexer.rs
+++ b/crates/syntax/src/parsing/lexer.rs
@@ -146,9 +146,9 @@ fn rustc_token_kind_to_syntax_kind(
146 rustc_lexer::TokenKind::RawIdent => IDENT, 146 rustc_lexer::TokenKind::RawIdent => IDENT,
147 rustc_lexer::TokenKind::Literal { kind, .. } => return match_literal_kind(&kind), 147 rustc_lexer::TokenKind::Literal { kind, .. } => return match_literal_kind(&kind),
148 148
149 rustc_lexer::TokenKind::Lifetime { starts_with_number: false } => LIFETIME, 149 rustc_lexer::TokenKind::Lifetime { starts_with_number: false } => LIFETIME_IDENT,
150 rustc_lexer::TokenKind::Lifetime { starts_with_number: true } => { 150 rustc_lexer::TokenKind::Lifetime { starts_with_number: true } => {
151 return (LIFETIME, Some("Lifetime name cannot start with a number")) 151 return (LIFETIME_IDENT, Some("Lifetime name cannot start with a number"))
152 } 152 }
153 153
154 rustc_lexer::TokenKind::Semi => T![;], 154 rustc_lexer::TokenKind::Semi => T![;],
diff --git a/crates/syntax/test_data/lexer/err/0057_lifetime_strarts_with_a_number.rs b/crates/syntax/test_data/lexer/err/0057_lifetime_starts_with_a_number.rs
index a7698a404..a7698a404 100644
--- a/crates/syntax/test_data/lexer/err/0057_lifetime_strarts_with_a_number.rs
+++ b/crates/syntax/test_data/lexer/err/0057_lifetime_starts_with_a_number.rs
diff --git a/crates/syntax/test_data/lexer/err/0057_lifetime_strarts_with_a_number.txt b/crates/syntax/test_data/lexer/err/0057_lifetime_starts_with_a_number.txt
index e138bcebc..11e0ae14a 100644
--- a/crates/syntax/test_data/lexer/err/0057_lifetime_strarts_with_a_number.txt
+++ b/crates/syntax/test_data/lexer/err/0057_lifetime_starts_with_a_number.txt
@@ -1,6 +1,6 @@
1LIFETIME 2 "\'1" 1LIFETIME_IDENT 2 "\'1"
2WHITESPACE 1 "\n" 2WHITESPACE 1 "\n"
3LIFETIME 10 "\'1lifetime" 3LIFETIME_IDENT 10 "\'1lifetime"
4WHITESPACE 1 "\n" 4WHITESPACE 1 "\n"
5> error0..2 token("\'1") msg(Lifetime name cannot start with a number) 5> error0..2 token("\'1") msg(Lifetime name cannot start with a number)
6> error3..13 token("\'1lifetime") msg(Lifetime name cannot start with a number) 6> error3..13 token("\'1lifetime") msg(Lifetime name cannot start with a number)
diff --git a/crates/syntax/test_data/lexer/ok/0007_lifetimes.txt b/crates/syntax/test_data/lexer/ok/0007_lifetimes.txt
index 005c29100..4d6625c3a 100644
--- a/crates/syntax/test_data/lexer/ok/0007_lifetimes.txt
+++ b/crates/syntax/test_data/lexer/ok/0007_lifetimes.txt
@@ -1,8 +1,8 @@
1LIFETIME 2 "\'a" 1LIFETIME_IDENT 2 "\'a"
2WHITESPACE 1 " " 2WHITESPACE 1 " "
3LIFETIME 4 "\'foo" 3LIFETIME_IDENT 4 "\'foo"
4WHITESPACE 1 " " 4WHITESPACE 1 " "
5LIFETIME 12 "\'foo_bar_baz" 5LIFETIME_IDENT 12 "\'foo_bar_baz"
6WHITESPACE 1 " " 6WHITESPACE 1 " "
7LIFETIME 2 "\'_" 7LIFETIME_IDENT 2 "\'_"
8WHITESPACE 1 "\n" 8WHITESPACE 1 "\n"
diff --git a/crates/syntax/test_data/parser/err/0024_many_type_parens.rast b/crates/syntax/test_data/parser/err/0024_many_type_parens.rast
index e3be6b22e..4c4ddf5ec 100644
--- a/crates/syntax/test_data/parser/err/0024_many_type_parens.rast
+++ b/crates/syntax/test_data/parser/err/0024_many_type_parens.rast
@@ -42,7 +42,8 @@ [email protected]
42 [email protected] 42 [email protected]
43 [email protected] "<" 43 [email protected] "<"
44 [email protected] 44 [email protected]
45 [email protected] "\'a" 45 [email protected]
46 [email protected] "\'a"
46 [email protected] ">" 47 [email protected] ">"
47 [email protected] " " 48 [email protected] " "
48 [email protected] 49 [email protected]
@@ -53,7 +54,8 @@ [email protected]
53 [email protected] 54 [email protected]
54 [email protected] "<" 55 [email protected] "<"
55 [email protected] 56 [email protected]
56 [email protected] "\'a" 57 [email protected]
58 [email protected] "\'a"
57 [email protected] ">" 59 [email protected] ">"
58 [email protected] ")" 60 [email protected] ")"
59 [email protected] ">" 61 [email protected] ">"
@@ -125,7 +127,8 @@ [email protected]
125 [email protected] 127 [email protected]
126 [email protected] "<" 128 [email protected] "<"
127 [email protected] 129 [email protected]
128 [email protected] "\'a" 130 [email protected]
131 [email protected] "\'a"
129 [email protected] ">" 132 [email protected] ">"
130 [email protected] " " 133 [email protected] " "
131 [email protected] 134 [email protected]
@@ -136,7 +139,8 @@ [email protected]
136 [email protected] 139 [email protected]
137 [email protected] "<" 140 [email protected] "<"
138 [email protected] 141 [email protected]
139 [email protected] "\'a" 142 [email protected]
143 [email protected] "\'a"
140 [email protected] ">" 144 [email protected] ">"
141 [email protected] ")" 145 [email protected] ")"
142 [email protected] 146 [email protected]
@@ -187,7 +191,7 @@ [email protected]
187 [email protected] 191 [email protected]
188 [email protected] "<" 192 [email protected] "<"
189 [email protected] 193 [email protected]
190 [email protected] "\'a" 194 LIFETIME_IDENT@155..157 "\'a"
191 [email protected] ">" 195 [email protected] ">"
192 [email protected] " " 196 [email protected] " "
193 [email protected] 197 [email protected]
@@ -201,7 +205,7 @@ [email protected]
201 [email protected] "Trait" 205 [email protected] "Trait"
202 [email protected] "<" 206 [email protected] "<"
203 [email protected] 207 [email protected]
204 [email protected] "\'a" 208 LIFETIME_IDENT@165..167 "\'a"
205 [email protected] ">" 209 [email protected] ">"
206 [email protected] 210 [email protected]
207 [email protected] ")" 211 [email protected] ")"
@@ -245,7 +249,8 @@ [email protected]
245 [email protected] 249 [email protected]
246 [email protected] "<" 250 [email protected] "<"
247 [email protected] 251 [email protected]
248 [email protected] "\'a" 252 [email protected]
253 [email protected] "\'a"
249 [email protected] ">" 254 [email protected] ">"
250 [email protected] " " 255 [email protected] " "
251 [email protected] 256 [email protected]
@@ -256,7 +261,8 @@ [email protected]
256 [email protected] 261 [email protected]
257 [email protected] "<" 262 [email protected] "<"
258 [email protected] 263 [email protected]
259 [email protected] "\'a" 264 [email protected]
265 [email protected] "\'a"
260 [email protected] ">" 266 [email protected] ">"
261 [email protected] ")" 267 [email protected] ")"
262 [email protected] " " 268 [email protected] " "
diff --git a/crates/syntax/test_data/parser/err/0027_incomplere_where_for.rast b/crates/syntax/test_data/parser/err/0027_incomplere_where_for.rast
index a8e42e6ea..c5215d6b1 100644
--- a/crates/syntax/test_data/parser/err/0027_incomplere_where_for.rast
+++ b/crates/syntax/test_data/parser/err/0027_incomplere_where_for.rast
@@ -16,7 +16,8 @@ [email protected]
16 [email protected] 16 [email protected]
17 [email protected] "<" 17 [email protected] "<"
18 [email protected] 18 [email protected]
19 [email protected] "\'a" 19 [email protected]
20 [email protected] "\'a"
20 [email protected] ">" 21 [email protected] ">"
21 [email protected] "\n" 22 [email protected] "\n"
22 [email protected] 23 [email protected]
diff --git a/crates/syntax/test_data/parser/err/0043_weird_blocks.rast b/crates/syntax/test_data/parser/err/0043_weird_blocks.rast
index df29017e7..e73bd1aea 100644
--- a/crates/syntax/test_data/parser/err/0043_weird_blocks.rast
+++ b/crates/syntax/test_data/parser/err/0043_weird_blocks.rast
@@ -54,7 +54,8 @@ [email protected]
54 [email protected] 54 [email protected]
55 [email protected] 55 [email protected]
56 [email protected] 56 [email protected]
57 [email protected] "\'label" 57 [email protected]
58 [email protected] "\'label"
58 [email protected] ":" 59 [email protected] ":"
59 [email protected] " " 60 [email protected] " "
60 [email protected] 61 [email protected]
diff --git a/crates/syntax/test_data/parser/err/0044_unexpected_for_type.rast b/crates/syntax/test_data/parser/err/0044_unexpected_for_type.rast
index 71aa86494..cc54185e5 100644
--- a/crates/syntax/test_data/parser/err/0044_unexpected_for_type.rast
+++ b/crates/syntax/test_data/parser/err/0044_unexpected_for_type.rast
@@ -12,12 +12,14 @@ [email protected]
12 [email protected] 12 [email protected]
13 [email protected] "<" 13 [email protected] "<"
14 [email protected] 14 [email protected]
15 [email protected] "\'a" 15 [email protected]
16 [email protected] "\'a"
16 [email protected] ">" 17 [email protected] ">"
17 [email protected] " " 18 [email protected] " "
18 [email protected] 19 [email protected]
19 [email protected] "&" 20 [email protected] "&"
20 [email protected] "\'a" 21 [email protected]
22 [email protected] "\'a"
21 [email protected] " " 23 [email protected] " "
22 [email protected] 24 [email protected]
23 [email protected] 25 [email protected]
@@ -39,14 +41,16 @@ [email protected]
39 [email protected] 41 [email protected]
40 [email protected] "<" 42 [email protected] "<"
41 [email protected] 43 [email protected]
42 [email protected] "\'a" 44 [email protected]
45 [email protected] "\'a"
43 [email protected] ">" 46 [email protected] ">"
44 [email protected] " " 47 [email protected] " "
45 [email protected] 48 [email protected]
46 [email protected] "(" 49 [email protected] "("
47 [email protected] 50 [email protected]
48 [email protected] "&" 51 [email protected] "&"
49 [email protected] "\'a" 52 [email protected]
53 [email protected] "\'a"
50 [email protected] " " 54 [email protected] " "
51 [email protected] 55 [email protected]
52 [email protected] 56 [email protected]
@@ -70,7 +74,8 @@ [email protected]
70 [email protected] 74 [email protected]
71 [email protected] "<" 75 [email protected] "<"
72 [email protected] 76 [email protected]
73 [email protected] "\'a" 77 [email protected]
78 [email protected] "\'a"
74 [email protected] ">" 79 [email protected] ">"
75 [email protected] " " 80 [email protected] " "
76 [email protected] 81 [email protected]
@@ -96,7 +101,8 @@ [email protected]
96 [email protected] 101 [email protected]
97 [email protected] "<" 102 [email protected] "<"
98 [email protected] 103 [email protected]
99 [email protected] "\'a" 104 [email protected]
105 [email protected] "\'a"
100 [email protected] ">" 106 [email protected] ">"
101 [email protected] " " 107 [email protected] " "
102 [email protected] 108 [email protected]
@@ -104,7 +110,8 @@ [email protected]
104 [email protected] 110 [email protected]
105 [email protected] "<" 111 [email protected] "<"
106 [email protected] 112 [email protected]
107 [email protected] "\'b" 113 [email protected]
114 [email protected] "\'b"
108 [email protected] ">" 115 [email protected] ">"
109 [email protected] " " 116 [email protected] " "
110 [email protected] 117 [email protected]
@@ -114,7 +121,8 @@ [email protected]
114 [email protected] 121 [email protected]
115 [email protected] 122 [email protected]
116 [email protected] "&" 123 [email protected] "&"
117 [email protected] "\'a" 124 [email protected]
125 [email protected] "\'a"
118 [email protected] " " 126 [email protected] " "
119 [email protected] 127 [email protected]
120 [email protected] 128 [email protected]
@@ -126,7 +134,8 @@ [email protected]
126 [email protected] 134 [email protected]
127 [email protected] 135 [email protected]
128 [email protected] "&" 136 [email protected] "&"
129 [email protected] "\'b" 137 [email protected]
138 [email protected] "\'b"
130 [email protected] " " 139 [email protected] " "
131 [email protected] 140 [email protected]
132 [email protected] 141 [email protected]
@@ -159,7 +168,8 @@ [email protected]
159 [email protected] 168 [email protected]
160 [email protected] "<" 169 [email protected] "<"
161 [email protected] 170 [email protected]
162 [email protected] "\'a" 171 [email protected]
172 [email protected] "\'a"
163 [email protected] ">" 173 [email protected] ">"
164 [email protected] " " 174 [email protected] " "
165 [email protected] 175 [email protected]
@@ -167,7 +177,8 @@ [email protected]
167 [email protected] 177 [email protected]
168 [email protected] "<" 178 [email protected] "<"
169 [email protected] 179 [email protected]
170 [email protected] "\'b" 180 [email protected]
181 [email protected] "\'b"
171 [email protected] ">" 182 [email protected] ">"
172 [email protected] " " 183 [email protected] " "
173 [email protected] 184 [email protected]
@@ -175,7 +186,8 @@ [email protected]
175 [email protected] 186 [email protected]
176 [email protected] "<" 187 [email protected] "<"
177 [email protected] 188 [email protected]
178 [email protected] "\'c" 189 [email protected]
190 [email protected] "\'c"
179 [email protected] ">" 191 [email protected] ">"
180 [email protected] " " 192 [email protected] " "
181 [email protected] 193 [email protected]
@@ -185,7 +197,8 @@ [email protected]
185 [email protected] 197 [email protected]
186 [email protected] 198 [email protected]
187 [email protected] "&" 199 [email protected] "&"
188 [email protected] "\'a" 200 [email protected]
201 [email protected] "\'a"
189 [email protected] " " 202 [email protected] " "
190 [email protected] 203 [email protected]
191 [email protected] 204 [email protected]
@@ -197,7 +210,8 @@ [email protected]
197 [email protected] 210 [email protected]
198 [email protected] 211 [email protected]
199 [email protected] "&" 212 [email protected] "&"
200 [email protected] "\'b" 213 [email protected]
214 [email protected] "\'b"
201 [email protected] " " 215 [email protected] " "
202 [email protected] 216 [email protected]
203 [email protected] 217 [email protected]
@@ -209,7 +223,8 @@ [email protected]
209 [email protected] 223 [email protected]
210 [email protected] 224 [email protected]
211 [email protected] "&" 225 [email protected] "&"
212 [email protected] "\'c" 226 [email protected]
227 [email protected] "\'c"
213 [email protected] " " 228 [email protected] " "
214 [email protected] 229 [email protected]
215 [email protected] 230 [email protected]
diff --git a/crates/syntax/test_data/parser/err/0046_ambiguous_trait_object.rast b/crates/syntax/test_data/parser/err/0046_ambiguous_trait_object.rast
index 592741cdb..7049f4734 100644
--- a/crates/syntax/test_data/parser/err/0046_ambiguous_trait_object.rast
+++ b/crates/syntax/test_data/parser/err/0046_ambiguous_trait_object.rast
@@ -7,14 +7,16 @@ [email protected]
7 [email protected] 7 [email protected]
8 [email protected] "<" 8 [email protected] "<"
9 [email protected] 9 [email protected]
10 [email protected] "\'a" 10 [email protected]
11 [email protected] "\'a"
11 [email protected] ">" 12 [email protected] ">"
12 [email protected] " " 13 [email protected] " "
13 [email protected] "=" 14 [email protected] "="
14 [email protected] " " 15 [email protected] " "
15 [email protected] 16 [email protected]
16 [email protected] "&" 17 [email protected] "&"
17 [email protected] "\'a" 18 [email protected]
19 [email protected] "\'a"
18 [email protected] " " 20 [email protected] " "
19 [email protected] 21 [email protected]
20 [email protected] "dyn" 22 [email protected] "dyn"
@@ -101,7 +103,8 @@ [email protected]
101 [email protected] "+" 103 [email protected] "+"
102 [email protected] " " 104 [email protected] " "
103 [email protected] 105 [email protected]
104 [email protected] "\'static" 106 [email protected]
107 [email protected] "\'static"
105 [email protected] ";" 108 [email protected] ";"
106 [email protected] "\n" 109 [email protected] "\n"
107 [email protected] 110 [email protected]
diff --git a/crates/syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast b/crates/syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast
index a4271fc87..0adf2cd5a 100644
--- a/crates/syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast
+++ b/crates/syntax/test_data/parser/inline/err/0002_misplaced_label_err.rast
@@ -14,7 +14,8 @@ [email protected]
14 [email protected] 14 [email protected]
15 [email protected] 15 [email protected]
16 [email protected] 16 [email protected]
17 [email protected] "\'loop" 17 [email protected]
18 [email protected] "\'loop"
18 [email protected] ":" 19 [email protected] ":"
19 [email protected] " " 20 [email protected] " "
20 [email protected] 21 [email protected]
diff --git a/crates/syntax/test_data/parser/inline/ok/0003_where_pred_for.rast b/crates/syntax/test_data/parser/inline/ok/0003_where_pred_for.rast
index 62da7b887..6cdfd058b 100644
--- a/crates/syntax/test_data/parser/inline/ok/0003_where_pred_for.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0003_where_pred_for.rast
@@ -22,7 +22,8 @@ [email protected]
22 [email protected] 22 [email protected]
23 [email protected] "<" 23 [email protected] "<"
24 [email protected] 24 [email protected]
25 [email protected] "\'a" 25 [email protected]
26 [email protected] "\'a"
26 [email protected] ">" 27 [email protected] ">"
27 [email protected] " " 28 [email protected] " "
28 [email protected] 29 [email protected]
@@ -44,7 +45,8 @@ [email protected]
44 [email protected] 45 [email protected]
45 [email protected] 46 [email protected]
46 [email protected] "&" 47 [email protected] "&"
47 [email protected] "\'a" 48 [email protected]
49 [email protected] "\'a"
48 [email protected] " " 50 [email protected] " "
49 [email protected] 51 [email protected]
50 [email protected] 52 [email protected]
diff --git a/crates/syntax/test_data/parser/inline/ok/0006_self_param.rast b/crates/syntax/test_data/parser/inline/ok/0006_self_param.rast
index d24ad7423..8048f5fad 100644
--- a/crates/syntax/test_data/parser/inline/ok/0006_self_param.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0006_self_param.rast
@@ -52,7 +52,8 @@ [email protected]
52 [email protected] "(" 52 [email protected] "("
53 [email protected] 53 [email protected]
54 [email protected] "&" 54 [email protected] "&"
55 [email protected] "\'a" 55 [email protected]
56 [email protected] "\'a"
56 [email protected] " " 57 [email protected] " "
57 [email protected] "self" 58 [email protected] "self"
58 [email protected] "," 59 [email protected] ","
@@ -71,7 +72,8 @@ [email protected]
71 [email protected] "(" 72 [email protected] "("
72 [email protected] 73 [email protected]
73 [email protected] "&" 74 [email protected] "&"
74 [email protected] "\'a" 75 [email protected]
76 [email protected] "\'a"
75 [email protected] " " 77 [email protected] " "
76 [email protected] "mut" 78 [email protected] "mut"
77 [email protected] " " 79 [email protected] " "
diff --git a/crates/syntax/test_data/parser/inline/ok/0007_type_param_bounds.rast b/crates/syntax/test_data/parser/inline/ok/0007_type_param_bounds.rast
index e95688f56..075b438d2 100644
--- a/crates/syntax/test_data/parser/inline/ok/0007_type_param_bounds.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0007_type_param_bounds.rast
@@ -13,7 +13,8 @@ [email protected]
13 [email protected] " " 13 [email protected] " "
14 [email protected] 14 [email protected]
15 [email protected] 15 [email protected]
16 [email protected] "\'a" 16 [email protected]
17 [email protected] "\'a"
17 [email protected] " " 18 [email protected] " "
18 [email protected] "+" 19 [email protected] "+"
19 [email protected] " " 20 [email protected] " "
diff --git a/crates/syntax/test_data/parser/inline/ok/0015_continue_expr.rast b/crates/syntax/test_data/parser/inline/ok/0015_continue_expr.rast
index 104e153ce..b9e92b57a 100644
--- a/crates/syntax/test_data/parser/inline/ok/0015_continue_expr.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0015_continue_expr.rast
@@ -26,7 +26,8 @@ [email protected]
26 [email protected] 26 [email protected]
27 [email protected] "continue" 27 [email protected] "continue"
28 [email protected] " " 28 [email protected] " "
29 [email protected] "\'l" 29 [email protected]
30 [email protected] "\'l"
30 [email protected] ";" 31 [email protected] ";"
31 [email protected] "\n " 32 [email protected] "\n "
32 [email protected] "}" 33 [email protected] "}"
diff --git a/crates/syntax/test_data/parser/inline/ok/0028_impl_trait_type.rast b/crates/syntax/test_data/parser/inline/ok/0028_impl_trait_type.rast
index 32b2959bd..dad4362b7 100644
--- a/crates/syntax/test_data/parser/inline/ok/0028_impl_trait_type.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0028_impl_trait_type.rast
@@ -31,13 +31,15 @@ [email protected]
31 [email protected] 31 [email protected]
32 [email protected] "<" 32 [email protected] "<"
33 [email protected] 33 [email protected]
34 [email protected] "\'a" 34 [email protected]
35 [email protected] "\'a"
35 [email protected] ">" 36 [email protected] ">"
36 [email protected] ">" 37 [email protected] ">"
37 [email protected] " " 38 [email protected] " "
38 [email protected] "+" 39 [email protected] "+"
39 [email protected] " " 40 [email protected] " "
40 [email protected] 41 [email protected]
41 [email protected] "\'a" 42 [email protected]
43 [email protected] "\'a"
42 [email protected] ";" 44 [email protected] ";"
43 [email protected] "\n" 45 [email protected] "\n"
diff --git a/crates/syntax/test_data/parser/inline/ok/0033_reference_type;.rast b/crates/syntax/test_data/parser/inline/ok/0033_reference_type;.rast
index 974df9f9a..ac0299268 100644
--- a/crates/syntax/test_data/parser/inline/ok/0033_reference_type;.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0033_reference_type;.rast
@@ -24,7 +24,8 @@ [email protected]
24 [email protected] " " 24 [email protected] " "
25 [email protected] 25 [email protected]
26 [email protected] "&" 26 [email protected] "&"
27 [email protected] "\'static" 27 [email protected]
28 [email protected] "\'static"
28 [email protected] " " 29 [email protected] " "
29 [email protected] 30 [email protected]
30 [email protected] "(" 31 [email protected] "("
diff --git a/crates/syntax/test_data/parser/inline/ok/0034_break_expr.rast b/crates/syntax/test_data/parser/inline/ok/0034_break_expr.rast
index f905def6f..828013d45 100644
--- a/crates/syntax/test_data/parser/inline/ok/0034_break_expr.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0034_break_expr.rast
@@ -26,7 +26,8 @@ [email protected]
26 [email protected] 26 [email protected]
27 [email protected] "break" 27 [email protected] "break"
28 [email protected] " " 28 [email protected] " "
29 [email protected] "\'l" 29 [email protected]
30 [email protected] "\'l"
30 [email protected] ";" 31 [email protected] ";"
31 [email protected] "\n " 32 [email protected] "\n "
32 [email protected] 33 [email protected]
@@ -41,7 +42,8 @@ [email protected]
41 [email protected] 42 [email protected]
42 [email protected] "break" 43 [email protected] "break"
43 [email protected] " " 44 [email protected] " "
44 [email protected] "\'l" 45 [email protected]
46 [email protected] "\'l"
45 [email protected] " " 47 [email protected] " "
46 [email protected] 48 [email protected]
47 [email protected] "92" 49 [email protected] "92"
diff --git a/crates/syntax/test_data/parser/inline/ok/0039_type_arg.rast b/crates/syntax/test_data/parser/inline/ok/0039_type_arg.rast
index 69e98b9d6..51e881a8e 100644
--- a/crates/syntax/test_data/parser/inline/ok/0039_type_arg.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0039_type_arg.rast
@@ -15,7 +15,8 @@ [email protected]
15 [email protected] 15 [email protected]
16 [email protected] "<" 16 [email protected] "<"
17 [email protected] 17 [email protected]
18 [email protected] "\'static" 18 [email protected]
19 [email protected] "\'static"
19 [email protected] "," 20 [email protected] ","
20 [email protected] " " 21 [email protected] " "
21 [email protected] 22 [email protected]
diff --git a/crates/syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast b/crates/syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast
index 6baea6e3c..b6f5a5689 100644
--- a/crates/syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0045_param_list_opt_patterns.rast
@@ -33,7 +33,8 @@ [email protected]
33 [email protected] 33 [email protected]
34 [email protected] "<" 34 [email protected] "<"
35 [email protected] 35 [email protected]
36 [email protected] "\'a" 36 [email protected]
37 [email protected] "\'a"
37 [email protected] ">" 38 [email protected] ">"
38 [email protected] ")" 39 [email protected] ")"
39 [email protected] ">" 40 [email protected] ">"
diff --git a/crates/syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.rast b/crates/syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.rast
index 4d8404e7c..7df6e190a 100644
--- a/crates/syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0048_path_type_with_bounds.rast
@@ -31,7 +31,8 @@ [email protected]
31 [email protected] "+" 31 [email protected] "+"
32 [email protected] " " 32 [email protected] " "
33 [email protected] 33 [email protected]
34 [email protected] "\'f" 34 [email protected]
35 [email protected] "\'f"
35 [email protected] ">" 36 [email protected] ">"
36 [email protected] " " 37 [email protected] " "
37 [email protected] 38 [email protected]
@@ -72,7 +73,8 @@ [email protected]
72 [email protected] "+" 73 [email protected] "+"
73 [email protected] " " 74 [email protected] " "
74 [email protected] 75 [email protected]
75 [email protected] "\'f" 76 [email protected]
77 [email protected] "\'f"
76 [email protected] ">" 78 [email protected] ">"
77 [email protected] " " 79 [email protected] " "
78 [email protected] 80 [email protected]
diff --git a/crates/syntax/test_data/parser/inline/ok/0056_where_clause.rast b/crates/syntax/test_data/parser/inline/ok/0056_where_clause.rast
index 28129c50c..61dea413d 100644
--- a/crates/syntax/test_data/parser/inline/ok/0056_where_clause.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0056_where_clause.rast
@@ -12,17 +12,20 @@ [email protected]
12 [email protected] "where" 12 [email protected] "where"
13 [email protected] "\n " 13 [email protected] "\n "
14 [email protected] 14 [email protected]
15 [email protected] "\'a" 15 [email protected]
16 [email protected] "\'a"
16 [email protected] ":" 17 [email protected] ":"
17 [email protected] " " 18 [email protected] " "
18 [email protected] 19 [email protected]
19 [email protected] 20 [email protected]
20 [email protected] "\'b" 21 [email protected]
22 [email protected] "\'b"
21 [email protected] " " 23 [email protected] " "
22 [email protected] "+" 24 [email protected] "+"
23 [email protected] " " 25 [email protected] " "
24 [email protected] 26 [email protected]
25 [email protected] "\'c" 27 [email protected]
28 [email protected] "\'c"
26 [email protected] "," 29 [email protected] ","
27 [email protected] "\n " 30 [email protected] "\n "
28 [email protected] 31 [email protected]
@@ -53,7 +56,8 @@ [email protected]
53 [email protected] "+" 56 [email protected] "+"
54 [email protected] " " 57 [email protected] " "
55 [email protected] 58 [email protected]
56 [email protected] "\'static" 59 [email protected]
60 [email protected] "\'static"
57 [email protected] "," 61 [email protected] ","
58 [email protected] "\n " 62 [email protected] "\n "
59 [email protected] 63 [email protected]
@@ -71,7 +75,8 @@ [email protected]
71 [email protected] " " 75 [email protected] " "
72 [email protected] 76 [email protected]
73 [email protected] 77 [email protected]
74 [email protected] "\'a" 78 [email protected]
79 [email protected] "\'a"
75 [email protected] "," 80 [email protected] ","
76 [email protected] "\n " 81 [email protected] "\n "
77 [email protected] 82 [email protected]
@@ -102,7 +107,8 @@ [email protected]
102 [email protected] " " 107 [email protected] " "
103 [email protected] 108 [email protected]
104 [email protected] 109 [email protected]
105 [email protected] "\'a" 110 [email protected]
111 [email protected] "\'a"
106 [email protected] "\n" 112 [email protected] "\n"
107 [email protected] 113 [email protected]
108 [email protected] "{" 114 [email protected] "{"
diff --git a/crates/syntax/test_data/parser/inline/ok/0065_dyn_trait_type.rast b/crates/syntax/test_data/parser/inline/ok/0065_dyn_trait_type.rast
index 3a7fcfe24..49d26cef4 100644
--- a/crates/syntax/test_data/parser/inline/ok/0065_dyn_trait_type.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0065_dyn_trait_type.rast
@@ -31,13 +31,15 @@ [email protected]
31 [email protected] 31 [email protected]
32 [email protected] "<" 32 [email protected] "<"
33 [email protected] 33 [email protected]
34 [email protected] "\'a" 34 [email protected]
35 [email protected] "\'a"
35 [email protected] ">" 36 [email protected] ">"
36 [email protected] ">" 37 [email protected] ">"
37 [email protected] " " 38 [email protected] " "
38 [email protected] "+" 39 [email protected] "+"
39 [email protected] " " 40 [email protected] " "
40 [email protected] 41 [email protected]
41 [email protected] "\'a" 42 [email protected]
43 [email protected] "\'a"
42 [email protected] ";" 44 [email protected] ";"
43 [email protected] "\n" 45 [email protected] "\n"
diff --git a/crates/syntax/test_data/parser/inline/ok/0081_for_type.rast b/crates/syntax/test_data/parser/inline/ok/0081_for_type.rast
index f319d5141..8c909b5af 100644
--- a/crates/syntax/test_data/parser/inline/ok/0081_for_type.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0081_for_type.rast
@@ -12,7 +12,8 @@ [email protected]
12 [email protected] 12 [email protected]
13 [email protected] "<" 13 [email protected] "<"
14 [email protected] 14 [email protected]
15 [email protected] "\'a" 15 [email protected]
16 [email protected] "\'a"
16 [email protected] ">" 17 [email protected] ">"
17 [email protected] " " 18 [email protected] " "
18 [email protected] 19 [email protected]
@@ -42,7 +43,8 @@ [email protected]
42 [email protected] 43 [email protected]
43 [email protected] "<" 44 [email protected] "<"
44 [email protected] 45 [email protected]
45 [email protected] "\'a" 46 [email protected]
47 [email protected] "\'a"
46 [email protected] ">" 48 [email protected] ">"
47 [email protected] " " 49 [email protected] " "
48 [email protected] 50 [email protected]
@@ -59,7 +61,8 @@ [email protected]
59 [email protected] 61 [email protected]
60 [email protected] 62 [email protected]
61 [email protected] "&" 63 [email protected] "&"
62 [email protected] "\'a" 64 [email protected]
65 [email protected] "\'a"
63 [email protected] " " 66 [email protected] " "
64 [email protected] 67 [email protected]
65 [email protected] "(" 68 [email protected] "("
@@ -87,7 +90,8 @@ [email protected]
87 [email protected] 90 [email protected]
88 [email protected] "<" 91 [email protected] "<"
89 [email protected] 92 [email protected]
90 [email protected] "\'a" 93 [email protected]
94 [email protected] "\'a"
91 [email protected] ">" 95 [email protected] ">"
92 [email protected] " " 96 [email protected] " "
93 [email protected] 97 [email protected]
@@ -100,7 +104,8 @@ [email protected]
100 [email protected] 104 [email protected]
101 [email protected] 105 [email protected]
102 [email protected] "&" 106 [email protected] "&"
103 [email protected] "\'a" 107 [email protected]
108 [email protected] "\'a"
104 [email protected] " " 109 [email protected] " "
105 [email protected] 110 [email protected]
106 [email protected] 111 [email protected]
diff --git a/crates/syntax/test_data/parser/inline/ok/0109_label.rast b/crates/syntax/test_data/parser/inline/ok/0109_label.rast
index c9588025c..860dfe608 100644
--- a/crates/syntax/test_data/parser/inline/ok/0109_label.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0109_label.rast
@@ -14,7 +14,8 @@ [email protected]
14 [email protected] 14 [email protected]
15 [email protected] 15 [email protected]
16 [email protected] 16 [email protected]
17 [email protected] "\'a" 17 [email protected]
18 [email protected] "\'a"
18 [email protected] ":" 19 [email protected] ":"
19 [email protected] " " 20 [email protected] " "
20 [email protected] "loop" 21 [email protected] "loop"
@@ -26,7 +27,8 @@ [email protected]
26 [email protected] 27 [email protected]
27 [email protected] 28 [email protected]
28 [email protected] 29 [email protected]
29 [email protected] "\'b" 30 [email protected]
31 [email protected] "\'b"
30 [email protected] ":" 32 [email protected] ":"
31 [email protected] " " 33 [email protected] " "
32 [email protected] "while" 34 [email protected] "while"
@@ -41,7 +43,8 @@ [email protected]
41 [email protected] "\n " 43 [email protected] "\n "
42 [email protected] 44 [email protected]
43 [email protected] 45 [email protected]
44 [email protected] "\'c" 46 [email protected]
47 [email protected] "\'c"
45 [email protected] ":" 48 [email protected] ":"
46 [email protected] " " 49 [email protected] " "
47 [email protected] "for" 50 [email protected] "for"
diff --git a/crates/syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast b/crates/syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast
index 570b95205..616aa984e 100644
--- a/crates/syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0122_generic_lifetime_type_attribute.rast
@@ -20,7 +20,8 @@ [email protected]
20 [email protected] ")" 20 [email protected] ")"
21 [email protected] "]" 21 [email protected] "]"
22 [email protected] " " 22 [email protected] " "
23 [email protected] "\'a" 23 [email protected]
24 [email protected] "\'a"
24 [email protected] "," 25 [email protected] ","
25 [email protected] " " 26 [email protected] " "
26 [email protected] 27 [email protected]
@@ -49,7 +50,8 @@ [email protected]
49 [email protected] " " 50 [email protected] " "
50 [email protected] 51 [email protected]
51 [email protected] "&" 52 [email protected] "&"
52 [email protected] "\'a" 53 [email protected]
54 [email protected] "\'a"
53 [email protected] " " 55 [email protected] " "
54 [email protected] 56 [email protected]
55 [email protected] 57 [email protected]
diff --git a/crates/syntax/test_data/parser/inline/ok/0161_labeled_block.rast b/crates/syntax/test_data/parser/inline/ok/0161_labeled_block.rast
index 9e9a5f9c5..c2dea1cc1 100644
--- a/crates/syntax/test_data/parser/inline/ok/0161_labeled_block.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0161_labeled_block.rast
@@ -14,7 +14,8 @@ [email protected]
14 [email protected] 14 [email protected]
15 [email protected] 15 [email protected]
16 [email protected] 16 [email protected]
17 [email protected] "\'label" 17 [email protected]
18 [email protected] "\'label"
18 [email protected] ":" 19 [email protected] ":"
19 [email protected] " " 20 [email protected] " "
20 [email protected] 21 [email protected]
diff --git a/crates/syntax/test_data/parser/ok/0018_struct_type_params.rast b/crates/syntax/test_data/parser/ok/0018_struct_type_params.rast
index 630aa0708..83e17757b 100644
--- a/crates/syntax/test_data/parser/ok/0018_struct_type_params.rast
+++ b/crates/syntax/test_data/parser/ok/0018_struct_type_params.rast
@@ -80,7 +80,8 @@ [email protected]
80 [email protected] 80 [email protected]
81 [email protected] "<" 81 [email protected] "<"
82 [email protected] 82 [email protected]
83 [email protected] "\'a" 83 [email protected]
84 [email protected] "\'a"
84 [email protected] ">" 85 [email protected] ">"
85 [email protected] ";" 86 [email protected] ";"
86 [email protected] "\n" 87 [email protected] "\n"
@@ -92,7 +93,8 @@ [email protected]
92 [email protected] 93 [email protected]
93 [email protected] "<" 94 [email protected] "<"
94 [email protected] 95 [email protected]
95 [email protected] "\'a" 96 [email protected]
97 [email protected] "\'a"
96 [email protected] ":" 98 [email protected] ":"
97 [email protected] ">" 99 [email protected] ">"
98 [email protected] ";" 100 [email protected] ";"
@@ -105,10 +107,12 @@ [email protected]
105 [email protected] 107 [email protected]
106 [email protected] "<" 108 [email protected] "<"
107 [email protected] 109 [email protected]
108 [email protected] "\'a" 110 [email protected]
111 [email protected] "\'a"
109 [email protected] ":" 112 [email protected] ":"
110 [email protected] " " 113 [email protected] " "
111 [email protected] "\'b" 114 [email protected]
115 [email protected] "\'b"
112 [email protected] ">" 116 [email protected] ">"
113 [email protected] ";" 117 [email protected] ";"
114 [email protected] "\n" 118 [email protected] "\n"
@@ -120,10 +124,12 @@ [email protected]
120 [email protected] 124 [email protected]
121 [email protected] "<" 125 [email protected] "<"
122 [email protected] 126 [email protected]
123 [email protected] "\'a" 127 [email protected]
128 [email protected] "\'a"
124 [email protected] ":" 129 [email protected] ":"
125 [email protected] " " 130 [email protected] " "
126 [email protected] "\'b" 131 [email protected]
132 [email protected] "\'b"
127 [email protected] " " 133 [email protected] " "
128 [email protected] "+" 134 [email protected] "+"
129 [email protected] " " 135 [email protected] " "
@@ -138,14 +144,17 @@ [email protected]
138 [email protected] 144 [email protected]
139 [email protected] "<" 145 [email protected] "<"
140 [email protected] 146 [email protected]
141 [email protected] "\'a" 147 [email protected]
148 [email protected] "\'a"
142 [email protected] ":" 149 [email protected] ":"
143 [email protected] " " 150 [email protected] " "
144 [email protected] "\'b" 151 [email protected]
152 [email protected] "\'b"
145 [email protected] " " 153 [email protected] " "
146 [email protected] "+" 154 [email protected] "+"
147 [email protected] " " 155 [email protected] " "
148 [email protected] "\'c" 156 [email protected]
157 [email protected] "\'c"
149 [email protected] ">" 158 [email protected] ">"
150 [email protected] ";" 159 [email protected] ";"
151 [email protected] "\n" 160 [email protected] "\n"
@@ -157,7 +166,8 @@ [email protected]
157 [email protected] 166 [email protected]
158 [email protected] "<" 167 [email protected] "<"
159 [email protected] 168 [email protected]
160 [email protected] "\'a" 169 [email protected]
170 [email protected] "\'a"
161 [email protected] "," 171 [email protected] ","
162 [email protected] ">" 172 [email protected] ">"
163 [email protected] ";" 173 [email protected] ";"
@@ -170,11 +180,13 @@ [email protected]
170 [email protected] 180 [email protected]
171 [email protected] "<" 181 [email protected] "<"
172 [email protected] 182 [email protected]
173 [email protected] "\'a" 183 [email protected]
184 [email protected] "\'a"
174 [email protected] "," 185 [email protected] ","
175 [email protected] " " 186 [email protected] " "
176 [email protected] 187 [email protected]
177 [email protected] "\'b" 188 [email protected]
189 [email protected] "\'b"
178 [email protected] ">" 190 [email protected] ">"
179 [email protected] ";" 191 [email protected] ";"
180 [email protected] "\n" 192 [email protected] "\n"
@@ -186,18 +198,22 @@ [email protected]
186 [email protected] 198 [email protected]
187 [email protected] "<" 199 [email protected] "<"
188 [email protected] 200 [email protected]
189 [email protected] "\'a" 201 [email protected]
202 [email protected] "\'a"
190 [email protected] ":" 203 [email protected] ":"
191 [email protected] " " 204 [email protected] " "
192 [email protected] "\'b" 205 [email protected]
206 [email protected] "\'b"
193 [email protected] "+" 207 [email protected] "+"
194 [email protected] "," 208 [email protected] ","
195 [email protected] " " 209 [email protected] " "
196 [email protected] 210 [email protected]
197 [email protected] "\'b" 211 [email protected]
212 [email protected] "\'b"
198 [email protected] ":" 213 [email protected] ":"
199 [email protected] " " 214 [email protected] " "
200 [email protected] "\'c" 215 [email protected]
216 [email protected] "\'c"
201 [email protected] "," 217 [email protected] ","
202 [email protected] ">" 218 [email protected] ">"
203 [email protected] ";" 219 [email protected] ";"
@@ -241,7 +257,8 @@ [email protected]
241 [email protected] 257 [email protected]
242 [email protected] "<" 258 [email protected] "<"
243 [email protected] 259 [email protected]
244 [email protected] "\'a" 260 [email protected]
261 [email protected] "\'a"
245 [email protected] "," 262 [email protected] ","
246 [email protected] " " 263 [email protected] " "
247 [email protected] 264 [email protected]
diff --git a/crates/syntax/test_data/parser/ok/0020_type_param_bounds.rast b/crates/syntax/test_data/parser/ok/0020_type_param_bounds.rast
index 9bdc50e1e..0612a71de 100644
--- a/crates/syntax/test_data/parser/ok/0020_type_param_bounds.rast
+++ b/crates/syntax/test_data/parser/ok/0020_type_param_bounds.rast
@@ -41,7 +41,8 @@ [email protected]
41 [email protected] " " 41 [email protected] " "
42 [email protected] 42 [email protected]
43 [email protected] 43 [email protected]
44 [email protected] "\'a" 44 [email protected]
45 [email protected] "\'a"
45 [email protected] ">" 46 [email protected] ">"
46 [email protected] ";" 47 [email protected] ";"
47 [email protected] "\n" 48 [email protected] "\n"
@@ -59,7 +60,8 @@ [email protected]
59 [email protected] " " 60 [email protected] " "
60 [email protected] 61 [email protected]
61 [email protected] 62 [email protected]
62 [email protected] "\'a" 63 [email protected]
64 [email protected] "\'a"
63 [email protected] " " 65 [email protected] " "
64 [email protected] "+" 66 [email protected] "+"
65 [email protected] " " 67 [email protected] " "
@@ -80,12 +82,14 @@ [email protected]
80 [email protected] " " 82 [email protected] " "
81 [email protected] 83 [email protected]
82 [email protected] 84 [email protected]
83 [email protected] "\'a" 85 [email protected]
86 [email protected] "\'a"
84 [email protected] " " 87 [email protected] " "
85 [email protected] "+" 88 [email protected] "+"
86 [email protected] " " 89 [email protected] " "
87 [email protected] 90 [email protected]
88 [email protected] "\'d" 91 [email protected]
92 [email protected] "\'d"
89 [email protected] " " 93 [email protected] " "
90 [email protected] ">" 94 [email protected] ">"
91 [email protected] ";" 95 [email protected] ";"
@@ -104,12 +108,14 @@ [email protected]
104 [email protected] " " 108 [email protected] " "
105 [email protected] 109 [email protected]
106 [email protected] 110 [email protected]
107 [email protected] "\'a" 111 [email protected]
112 [email protected] "\'a"
108 [email protected] " " 113 [email protected] " "
109 [email protected] "+" 114 [email protected] "+"
110 [email protected] " " 115 [email protected] " "
111 [email protected] 116 [email protected]
112 [email protected] "\'d" 117 [email protected]
118 [email protected] "\'d"
113 [email protected] " " 119 [email protected] " "
114 [email protected] "+" 120 [email protected] "+"
115 [email protected] " " 121 [email protected] " "
@@ -190,7 +196,8 @@ [email protected]
190 [email protected] "+" 196 [email protected] "+"
191 [email protected] " " 197 [email protected] " "
192 [email protected] 198 [email protected]
193 [email protected] "\'a" 199 [email protected]
200 [email protected] "\'a"
194 [email protected] ">" 201 [email protected] ">"
195 [email protected] ";" 202 [email protected] ";"
196 [email protected] "\n" 203 [email protected] "\n"
@@ -225,21 +232,26 @@ [email protected]
225 [email protected] 232 [email protected]
226 [email protected] "<" 233 [email protected] "<"
227 [email protected] 234 [email protected]
228 [email protected] "\'a" 235 [email protected]
236 [email protected] "\'a"
229 [email protected] ":" 237 [email protected] ":"
230 [email protected] " " 238 [email protected] " "
231 [email protected] "\'d" 239 [email protected]
240 [email protected] "\'d"
232 [email protected] "," 241 [email protected] ","
233 [email protected] " " 242 [email protected] " "
234 [email protected] 243 [email protected]
235 [email protected] "\'d" 244 [email protected]
245 [email protected] "\'d"
236 [email protected] ":" 246 [email protected] ":"
237 [email protected] " " 247 [email protected] " "
238 [email protected] "\'a" 248 [email protected]
249 [email protected] "\'a"
239 [email protected] " " 250 [email protected] " "
240 [email protected] "+" 251 [email protected] "+"
241 [email protected] " " 252 [email protected] " "
242 [email protected] "\'b" 253 [email protected]
254 [email protected] "\'b"
243 [email protected] "," 255 [email protected] ","
244 [email protected] " " 256 [email protected] " "
245 [email protected] 257 [email protected]
@@ -249,12 +261,14 @@ [email protected]
249 [email protected] " " 261 [email protected] " "
250 [email protected] 262 [email protected]
251 [email protected] 263 [email protected]
252 [email protected] "\'a" 264 [email protected]
265 [email protected] "\'a"
253 [email protected] " " 266 [email protected] " "
254 [email protected] "+" 267 [email protected] "+"
255 [email protected] " " 268 [email protected] " "
256 [email protected] 269 [email protected]
257 [email protected] "\'d" 270 [email protected]
271 [email protected] "\'d"
258 [email protected] " " 272 [email protected] " "
259 [email protected] "+" 273 [email protected] "+"
260 [email protected] " " 274 [email protected] " "
diff --git a/crates/syntax/test_data/parser/ok/0032_where_for.rast b/crates/syntax/test_data/parser/ok/0032_where_for.rast
index d59548f21..0cb2eca33 100644
--- a/crates/syntax/test_data/parser/ok/0032_where_for.rast
+++ b/crates/syntax/test_data/parser/ok/0032_where_for.rast
@@ -41,7 +41,8 @@ [email protected]
41 [email protected] 41 [email protected]
42 [email protected] "<" 42 [email protected] "<"
43 [email protected] 43 [email protected]
44 [email protected] "\'de" 44 [email protected]
45 [email protected] "\'de"
45 [email protected] ">" 46 [email protected] ">"
46 [email protected] " " 47 [email protected] " "
47 [email protected] 48 [email protected]
@@ -52,7 +53,8 @@ [email protected]
52 [email protected] 53 [email protected]
53 [email protected] "<" 54 [email protected] "<"
54 [email protected] 55 [email protected]
55 [email protected] "\'de" 56 [email protected]
57 [email protected] "\'de"
56 [email protected] ">" 58 [email protected] ">"
57 [email protected] " " 59 [email protected] " "
58 [email protected] "+" 60 [email protected] "+"
diff --git a/crates/syntax/test_data/parser/ok/0033_label_break.rast b/crates/syntax/test_data/parser/ok/0033_label_break.rast
index 88800ca7a..487e073ba 100644
--- a/crates/syntax/test_data/parser/ok/0033_label_break.rast
+++ b/crates/syntax/test_data/parser/ok/0033_label_break.rast
@@ -16,7 +16,8 @@ [email protected]
16 [email protected] 16 [email protected]
17 [email protected] 17 [email protected]
18 [email protected] 18 [email protected]
19 [email protected] "\'empty_block" 19 [email protected]
20 [email protected] "\'empty_block"
20 [email protected] ":" 21 [email protected] ":"
21 [email protected] " " 22 [email protected] " "
22 [email protected] 23 [email protected]
@@ -26,7 +27,8 @@ [email protected]
26 [email protected] 27 [email protected]
27 [email protected] 28 [email protected]
28 [email protected] 29 [email protected]
29 [email protected] "\'block" 30 [email protected]
31 [email protected] "\'block"
30 [email protected] ":" 32 [email protected] ":"
31 [email protected] " " 33 [email protected] " "
32 [email protected] 34 [email protected]
@@ -66,7 +68,8 @@ [email protected]
66 [email protected] 68 [email protected]
67 [email protected] "break" 69 [email protected] "break"
68 [email protected] " " 70 [email protected] " "
69 [email protected] "\'block" 71 [email protected]
72 [email protected] "\'block"
70 [email protected] ";" 73 [email protected] ";"
71 [email protected] "\n " 74 [email protected] "\n "
72 [email protected] "}" 75 [email protected] "}"
@@ -105,7 +108,8 @@ [email protected]
105 [email protected] 108 [email protected]
106 [email protected] "break" 109 [email protected] "break"
107 [email protected] " " 110 [email protected] " "
108 [email protected] "\'block" 111 [email protected]
112 [email protected] "\'block"
109 [email protected] ";" 113 [email protected] ";"
110 [email protected] "\n " 114 [email protected] "\n "
111 [email protected] "}" 115 [email protected] "}"
@@ -135,7 +139,8 @@ [email protected]
135 [email protected] " " 139 [email protected] " "
136 [email protected] 140 [email protected]
137 [email protected] 141 [email protected]
138 [email protected] "\'block" 142 [email protected]
143 [email protected] "\'block"
139 [email protected] ":" 144 [email protected] ":"
140 [email protected] " " 145 [email protected] " "
141 [email protected] 146 [email protected]
@@ -165,7 +170,8 @@ [email protected]
165 [email protected] 170 [email protected]
166 [email protected] "break" 171 [email protected] "break"
167 [email protected] " " 172 [email protected] " "
168 [email protected] "\'block" 173 [email protected]
174 [email protected] "\'block"
169 [email protected] " " 175 [email protected] " "
170 [email protected] 176 [email protected]
171 [email protected] "1" 177 [email protected] "1"
@@ -197,7 +203,8 @@ [email protected]
197 [email protected] 203 [email protected]
198 [email protected] "break" 204 [email protected] "break"
199 [email protected] " " 205 [email protected] " "
200 [email protected] "\'block" 206 [email protected]
207 [email protected] "\'block"
201 [email protected] " " 208 [email protected] " "
202 [email protected] 209 [email protected]
203 [email protected] "2" 210 [email protected] "2"
diff --git a/crates/syntax/test_data/parser/ok/0035_weird_exprs.rast b/crates/syntax/test_data/parser/ok/0035_weird_exprs.rast
index 7c61b5006..46b192dc1 100644
--- a/crates/syntax/test_data/parser/ok/0035_weird_exprs.rast
+++ b/crates/syntax/test_data/parser/ok/0035_weird_exprs.rast
@@ -1373,14 +1373,14 @@ [email protected]
1373 [email protected] " " 1373 [email protected] " "
1374 [email protected] "u8" 1374 [email protected] "u8"
1375 [email protected] "<" 1375 [email protected] "<"
1376 [email protected] "\'u8" 1376 LIFETIME_IDENT@2380..2383 "\'u8"
1377 [email protected] ":" 1377 [email protected] ":"
1378 [email protected] " " 1378 [email protected] " "
1379 [email protected] "\'u8" 1379 LIFETIME_IDENT@2385..2388 "\'u8"
1380 [email protected] " " 1380 [email protected] " "
1381 [email protected] "+" 1381 [email protected] "+"
1382 [email protected] " " 1382 [email protected] " "
1383 [email protected] "\'u8" 1383 LIFETIME_IDENT@2391..2394 "\'u8"
1384 [email protected] ">" 1384 [email protected] ">"
1385 [email protected] 1385 [email protected]
1386 [email protected] "(" 1386 [email protected] "("
@@ -1388,7 +1388,7 @@ [email protected]
1388 [email protected] ":" 1388 [email protected] ":"
1389 [email protected] " " 1389 [email protected] " "
1390 [email protected] "&" 1390 [email protected] "&"
1391 [email protected] "\'u8" 1391 LIFETIME_IDENT@2401..2404 "\'u8"
1392 [email protected] " " 1392 [email protected] " "
1393 [email protected] "u8" 1393 [email protected] "u8"
1394 [email protected] ")" 1394 [email protected] ")"
@@ -1397,7 +1397,7 @@ [email protected]
1397 [email protected] ">" 1397 [email protected] ">"
1398 [email protected] " " 1398 [email protected] " "
1399 [email protected] "&" 1399 [email protected] "&"
1400 [email protected] "\'u8" 1400 LIFETIME_IDENT@2413..2416 "\'u8"
1401 [email protected] " " 1401 [email protected] " "
1402 [email protected] "u8" 1402 [email protected] "u8"
1403 [email protected] " " 1403 [email protected] " "
@@ -1568,7 +1568,8 @@ [email protected]
1568 [email protected] 1568 [email protected]
1569 [email protected] "<" 1569 [email protected] "<"
1570 [email protected] 1570 [email protected]
1571 [email protected] "\'union" 1571 [email protected]
1572 [email protected] "\'union"
1572 [email protected] ">" 1573 [email protected] ">"
1573 [email protected] " " 1574 [email protected] " "
1574 [email protected] 1575 [email protected]
@@ -1581,7 +1582,8 @@ [email protected]
1581 [email protected] " " 1582 [email protected] " "
1582 [email protected] 1583 [email protected]
1583 [email protected] "&" 1584 [email protected] "&"
1584 [email protected] "\'union" 1585 [email protected]
1586 [email protected] "\'union"
1585 [email protected] " " 1587 [email protected] " "
1586 [email protected] 1588 [email protected]
1587 [email protected] 1589 [email protected]
@@ -1591,7 +1593,8 @@ [email protected]
1591 [email protected] 1593 [email protected]
1592 [email protected] "<" 1594 [email protected] "<"
1593 [email protected] 1595 [email protected]
1594 [email protected] "\'union" 1596 [email protected]
1597 [email protected] "\'union"
1595 [email protected] ">" 1598 [email protected] ">"
1596 [email protected] "," 1599 [email protected] ","
1597 [email protected] " " 1600 [email protected] " "
diff --git a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast b/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast
index d4f05f279..8974f9e40 100644
--- a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast
+++ b/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast
@@ -175,7 +175,8 @@ [email protected]
175 [email protected] 175 [email protected]
176 [email protected] "<" 176 [email protected] "<"
177 [email protected] 177 [email protected]
178 [email protected] "\'a" 178 [email protected]
179 [email protected] "\'a"
179 [email protected] ">" 180 [email protected] ">"
180 [email protected] ")" 181 [email protected] ")"
181 [email protected] ">" 182 [email protected] ">"
@@ -344,7 +345,8 @@ [email protected]
344 [email protected] 345 [email protected]
345 [email protected] "<" 346 [email protected] "<"
346 [email protected] 347 [email protected]
347 [email protected] "\'a" 348 [email protected]
349 [email protected] "\'a"
348 [email protected] ">" 350 [email protected] ">"
349 [email protected] 351 [email protected]
350 [email protected] "(" 352 [email protected] "("
@@ -376,7 +378,8 @@ [email protected]
376 [email protected] 378 [email protected]
377 [email protected] "<" 379 [email protected] "<"
378 [email protected] 380 [email protected]
379 [email protected] "\'a" 381 [email protected]
382 [email protected] "\'a"
380 [email protected] ">" 383 [email protected] ">"
381 [email protected] 384 [email protected]
382 [email protected] "(" 385 [email protected] "("
@@ -391,7 +394,8 @@ [email protected]
391 [email protected] " " 394 [email protected] " "
392 [email protected] 395 [email protected]
393 [email protected] "&" 396 [email protected] "&"
394 [email protected] "\'a" 397 [email protected]
398 [email protected] "\'a"
395 [email protected] " " 399 [email protected] " "
396 [email protected] "self" 400 [email protected] "self"
397 [email protected] ")" 401 [email protected] ")"
@@ -408,7 +412,8 @@ [email protected]
408 [email protected] 412 [email protected]
409 [email protected] "<" 413 [email protected] "<"
410 [email protected] 414 [email protected]
411 [email protected] "\'a" 415 [email protected]
416 [email protected] "\'a"
412 [email protected] ">" 417 [email protected] ">"
413 [email protected] 418 [email protected]
414 [email protected] "(" 419 [email protected] "("
@@ -423,7 +428,8 @@ [email protected]
423 [email protected] " " 428 [email protected] " "
424 [email protected] 429 [email protected]
425 [email protected] "&" 430 [email protected] "&"
426 [email protected] "\'a" 431 [email protected]
432 [email protected] "\'a"
427 [email protected] " " 433 [email protected] " "
428 [email protected] "mut" 434 [email protected] "mut"
429 [email protected] " " 435 [email protected] " "
diff --git a/crates/syntax/test_data/parser/ok/0067_where_for_pred.rast b/crates/syntax/test_data/parser/ok/0067_where_for_pred.rast
index 8f8639a37..325e9e655 100644
--- a/crates/syntax/test_data/parser/ok/0067_where_for_pred.rast
+++ b/crates/syntax/test_data/parser/ok/0067_where_for_pred.rast
@@ -22,7 +22,8 @@ [email protected]
22 [email protected] 22 [email protected]
23 [email protected] "<" 23 [email protected] "<"
24 [email protected] 24 [email protected]
25 [email protected] "\'a" 25 [email protected]
26 [email protected] "\'a"
26 [email protected] ">" 27 [email protected] ">"
27 [email protected] " " 28 [email protected] " "
28 [email protected] 29 [email protected]
@@ -44,7 +45,8 @@ [email protected]
44 [email protected] 45 [email protected]
45 [email protected] 46 [email protected]
46 [email protected] "&" 47 [email protected] "&"
47 [email protected] "\'a" 48 [email protected]
49 [email protected] "\'a"
48 [email protected] " " 50 [email protected] " "
49 [email protected] 51 [email protected]
50 [email protected] 52 [email protected]
@@ -82,12 +84,14 @@ [email protected]
82 [email protected] 84 [email protected]
83 [email protected] "<" 85 [email protected] "<"
84 [email protected] 86 [email protected]
85 [email protected] "\'a" 87 [email protected]
88 [email protected] "\'a"
86 [email protected] ">" 89 [email protected] ">"
87 [email protected] " " 90 [email protected] " "
88 [email protected] 91 [email protected]
89 [email protected] "&" 92 [email protected] "&"
90 [email protected] "\'a" 93 [email protected]
94 [email protected] "\'a"
91 [email protected] " " 95 [email protected] " "
92 [email protected] 96 [email protected]
93 [email protected] 97 [email protected]
@@ -133,14 +137,16 @@ [email protected]
133 [email protected] 137 [email protected]
134 [email protected] "<" 138 [email protected] "<"
135 [email protected] 139 [email protected]
136 [email protected] "\'a" 140 [email protected]
141 [email protected] "\'a"
137 [email protected] ">" 142 [email protected] ">"
138 [email protected] " " 143 [email protected] " "
139 [email protected] 144 [email protected]
140 [email protected] "(" 145 [email protected] "("
141 [email protected] 146 [email protected]
142 [email protected] "&" 147 [email protected] "&"
143 [email protected] "\'a" 148 [email protected]
149 [email protected] "\'a"
144 [email protected] " " 150 [email protected] " "
145 [email protected] 151 [email protected]
146 [email protected] 152 [email protected]
@@ -162,7 +168,8 @@ [email protected]
162 [email protected] 168 [email protected]
163 [email protected] 169 [email protected]
164 [email protected] "&" 170 [email protected] "&"
165 [email protected] "\'a" 171 [email protected]
172 [email protected] "\'a"
166 [email protected] " " 173 [email protected] " "
167 [email protected] 174 [email protected]
168 [email protected] 175 [email protected]
@@ -200,14 +207,16 @@ [email protected]
200 [email protected] 207 [email protected]
201 [email protected] "<" 208 [email protected] "<"
202 [email protected] 209 [email protected]
203 [email protected] "\'a" 210 [email protected]
211 [email protected] "\'a"
204 [email protected] ">" 212 [email protected] ">"
205 [email protected] " " 213 [email protected] " "
206 [email protected] 214 [email protected]
207 [email protected] "[" 215 [email protected] "["
208 [email protected] 216 [email protected]
209 [email protected] "&" 217 [email protected] "&"
210 [email protected] "\'a" 218 [email protected]
219 [email protected] "\'a"
211 [email protected] " " 220 [email protected] " "
212 [email protected] 221 [email protected]
213 [email protected] 222 [email protected]
@@ -267,7 +276,8 @@ [email protected]
267 [email protected] 276 [email protected]
268 [email protected] "<" 277 [email protected] "<"
269 [email protected] 278 [email protected]
270 [email protected] "\'a" 279 [email protected]
280 [email protected] "\'a"
271 [email protected] ">" 281 [email protected] ">"
272 [email protected] " " 282 [email protected] " "
273 [email protected] 283 [email protected]
@@ -277,7 +287,8 @@ [email protected]
277 [email protected] "<" 287 [email protected] "<"
278 [email protected] 288 [email protected]
279 [email protected] "&" 289 [email protected] "&"
280 [email protected] "\'a" 290 [email protected]
291 [email protected] "\'a"
281 [email protected] " " 292 [email protected] " "
282 [email protected] 293 [email protected]
283 [email protected] 294 [email protected]
@@ -336,7 +347,8 @@ [email protected]
336 [email protected] 347 [email protected]
337 [email protected] "<" 348 [email protected] "<"
338 [email protected] 349 [email protected]
339 [email protected] "\'a" 350 [email protected]
351 [email protected] "\'a"
340 [email protected] ">" 352 [email protected] ">"
341 [email protected] " " 353 [email protected] " "
342 [email protected] 354 [email protected]
@@ -344,7 +356,8 @@ [email protected]
344 [email protected] 356 [email protected]
345 [email protected] "<" 357 [email protected] "<"
346 [email protected] 358 [email protected]
347 [email protected] "\'b" 359 [email protected]
360 [email protected] "\'b"
348 [email protected] ">" 361 [email protected] ">"
349 [email protected] " " 362 [email protected] " "
350 [email protected] 363 [email protected]
@@ -354,7 +367,8 @@ [email protected]
354 [email protected] 367 [email protected]
355 [email protected] 368 [email protected]
356 [email protected] "&" 369 [email protected] "&"
357 [email protected] "\'a" 370 [email protected]
371 [email protected] "\'a"
358 [email protected] " " 372 [email protected] " "
359 [email protected] 373 [email protected]
360 [email protected] 374 [email protected]
@@ -366,7 +380,8 @@ [email protected]
366 [email protected] 380 [email protected]
367 [email protected] 381 [email protected]
368 [email protected] "&" 382 [email protected] "&"
369 [email protected] "\'b" 383 [email protected]
384 [email protected] "\'b"
370 [email protected] " " 385 [email protected] " "
371 [email protected] 386 [email protected]
372 [email protected] 387 [email protected]
diff --git a/crates/syntax/test_data/parser/ok/0069_multi_trait_object.rast b/crates/syntax/test_data/parser/ok/0069_multi_trait_object.rast
index 0cd868a83..8d3e187ae 100644
--- a/crates/syntax/test_data/parser/ok/0069_multi_trait_object.rast
+++ b/crates/syntax/test_data/parser/ok/0069_multi_trait_object.rast
@@ -7,14 +7,16 @@ [email protected]
7 [email protected] 7 [email protected]
8 [email protected] "<" 8 [email protected] "<"
9 [email protected] 9 [email protected]
10 [email protected] "\'a" 10 [email protected]
11 [email protected] "\'a"
11 [email protected] ">" 12 [email protected] ">"
12 [email protected] " " 13 [email protected] " "
13 [email protected] "=" 14 [email protected] "="
14 [email protected] " " 15 [email protected] " "
15 [email protected] 16 [email protected]
16 [email protected] "&" 17 [email protected] "&"
17 [email protected] "\'a" 18 [email protected]
19 [email protected] "\'a"
18 [email protected] " " 20 [email protected] " "
19 [email protected] 21 [email protected]
20 [email protected] "(" 22 [email protected] "("
@@ -109,7 +111,8 @@ [email protected]
109 [email protected] "+" 111 [email protected] "+"
110 [email protected] " " 112 [email protected] " "
111 [email protected] 113 [email protected]
112 [email protected] "\'static" 114 [email protected]
115 [email protected] "\'static"
113 [email protected] ")" 116 [email protected] ")"
114 [email protected] ";" 117 [email protected] ";"
115 [email protected] "\n" 118 [email protected] "\n"
diff --git a/docs/dev/README.md b/docs/dev/README.md
index 2795f6b5c..4a2f9feb3 100644
--- a/docs/dev/README.md
+++ b/docs/dev/README.md
@@ -292,3 +292,17 @@ Release steps:
2924. Tweet 2924. Tweet
2935. Inside `rust-analyzer`, run `cargo xtask promote` -- this will create a PR to rust-lang/rust updating rust-analyzer's submodule. 2935. Inside `rust-analyzer`, run `cargo xtask promote` -- this will create a PR to rust-lang/rust updating rust-analyzer's submodule.
294 Self-approve the PR. 294 Self-approve the PR.
295
296# Permissions
297
298There are three sets of people with extra permissions:
299
300* rust-analyzer GitHub organization **admins** (which include current t-compiler leads).
301 Admins have full access to the org.
302* **review** team in the organization.
303 Reviewers have `r+` access to all of organization's repositories and publish rights on crates.io.
304 They also have direct commit access, but all changes should via bors queue.
305 It's ok to self-approve if you think you know what you are doing!
306 bors should automatically sync the permissions.
307* **triage** team in the organization.
308 This team can label and close issues.
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json
index e83b116a7..2d717e366 100644
--- a/editors/code/package-lock.json
+++ b/editors/code/package-lock.json
@@ -195,9 +195,9 @@
195 } 195 }
196 }, 196 },
197 "@types/vscode": { 197 "@types/vscode": {
198 "version": "1.51.0", 198 "version": "1.52.0",
199 "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.51.0.tgz", 199 "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.52.0.tgz",
200 "integrity": "sha512-C/jZ35OT5k/rsJyAK8mS1kM++vMcm89oSWegkzxRCvHllIq0cToZAkIDs6eCY4SKrvik3nrhELizyLcM0onbQA==", 200 "integrity": "sha512-Kt3bvWzAvvF/WH9YEcrCICDp0Z7aHhJGhLJ1BxeyNP6yRjonWqWnAIh35/pXAjswAnWOABrYlF7SwXR9+1nnLA==",
201 "dev": true 201 "dev": true
202 }, 202 },
203 "@typescript-eslint/eslint-plugin": { 203 "@typescript-eslint/eslint-plugin": {
@@ -455,8 +455,7 @@
455 "balanced-match": { 455 "balanced-match": {
456 "version": "1.0.0", 456 "version": "1.0.0",
457 "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 457 "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
458 "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 458 "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
459 "dev": true
460 }, 459 },
461 "binary-extensions": { 460 "binary-extensions": {
462 "version": "2.1.0", 461 "version": "2.1.0",
@@ -474,7 +473,6 @@
474 "version": "1.1.11", 473 "version": "1.1.11",
475 "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 474 "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
476 "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 475 "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
477 "dev": true,
478 "requires": { 476 "requires": {
479 "balanced-match": "^1.0.0", 477 "balanced-match": "^1.0.0",
480 "concat-map": "0.0.1" 478 "concat-map": "0.0.1"
@@ -673,8 +671,7 @@
673 "concat-map": { 671 "concat-map": {
674 "version": "0.0.1", 672 "version": "0.0.1",
675 "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 673 "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
676 "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 674 "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
677 "dev": true
678 }, 675 },
679 "cross-spawn": { 676 "cross-spawn": {
680 "version": "7.0.3", 677 "version": "7.0.3",
@@ -1622,7 +1619,6 @@
1622 "version": "3.0.4", 1619 "version": "3.0.4",
1623 "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1620 "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
1624 "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1621 "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
1625 "dev": true,
1626 "requires": { 1622 "requires": {
1627 "brace-expansion": "^1.1.7" 1623 "brace-expansion": "^1.1.7"
1628 } 1624 }
@@ -2021,9 +2017,27 @@
2021 "dev": true 2017 "dev": true
2022 }, 2018 },
2023 "semver": { 2019 "semver": {
2024 "version": "6.3.0", 2020 "version": "7.3.4",
2025 "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 2021 "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
2026 "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" 2022 "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
2023 "requires": {
2024 "lru-cache": "^6.0.0"
2025 },
2026 "dependencies": {
2027 "lru-cache": {
2028 "version": "6.0.0",
2029 "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
2030 "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
2031 "requires": {
2032 "yallist": "^4.0.0"
2033 }
2034 },
2035 "yallist": {
2036 "version": "4.0.0",
2037 "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
2038 "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
2039 }
2040 }
2027 }, 2041 },
2028 "serialize-javascript": { 2042 "serialize-javascript": {
2029 "version": "5.0.1", 2043 "version": "5.0.1",
@@ -2350,32 +2364,33 @@
2350 } 2364 }
2351 }, 2365 },
2352 "vscode-jsonrpc": { 2366 "vscode-jsonrpc": {
2353 "version": "6.0.0-next.7", 2367 "version": "6.0.0",
2354 "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0-next.7.tgz", 2368 "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
2355 "integrity": "sha512-1nG+6cuTtpzmXe7yYfO9GCkYlyV6Ai+jDnwidHiT2T7zhc+bJM+VTtc0T/CdTlDyTNTqIcCj0V1nD4TcVjJ7Ug==" 2369 "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg=="
2356 }, 2370 },
2357 "vscode-languageclient": { 2371 "vscode-languageclient": {
2358 "version": "7.0.0-next.14", 2372 "version": "7.0.0",
2359 "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0-next.14.tgz", 2373 "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz",
2360 "integrity": "sha512-QUccfXK2F6AXXRFR8QJCaIz7N2BhJK6ok8E1aO8LHq2IBU33+5hTSJBXs7nEqrqZ/cY2VlDDbMWtMvCxz+/y1w==", 2374 "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==",
2361 "requires": { 2375 "requires": {
2362 "semver": "^6.3.0", 2376 "minimatch": "^3.0.4",
2363 "vscode-languageserver-protocol": "3.16.0-next.11" 2377 "semver": "^7.3.4",
2378 "vscode-languageserver-protocol": "3.16.0"
2364 } 2379 }
2365 }, 2380 },
2366 "vscode-languageserver-protocol": { 2381 "vscode-languageserver-protocol": {
2367 "version": "3.16.0-next.11", 2382 "version": "3.16.0",
2368 "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0-next.11.tgz", 2383 "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
2369 "integrity": "sha512-31FmupmSmfznuMuGp7qN6h3d/hKUbexbvcwTvrUE/igqRlzFU542s8MtGICx1ERbVuDOLGp96W2Z92qbUbmBPA==", 2384 "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
2370 "requires": { 2385 "requires": {
2371 "vscode-jsonrpc": "6.0.0-next.7", 2386 "vscode-jsonrpc": "6.0.0",
2372 "vscode-languageserver-types": "3.16.0-next.5" 2387 "vscode-languageserver-types": "3.16.0"
2373 } 2388 }
2374 }, 2389 },
2375 "vscode-languageserver-types": { 2390 "vscode-languageserver-types": {
2376 "version": "3.16.0-next.5", 2391 "version": "3.16.0",
2377 "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.5.tgz", 2392 "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
2378 "integrity": "sha512-lf8Y1XXMtF1r2oDDAmJe+drizNXkybSRXAQQk5dPy2rYJsY9SPXYNO074L3THu9zNYepzV5fRJZUPo/V/TLBRQ==" 2393 "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
2379 }, 2394 },
2380 "vscode-test": { 2395 "vscode-test": {
2381 "version": "1.4.1", 2396 "version": "1.4.1",
diff --git a/editors/code/package.json b/editors/code/package.json
index 160a62e46..ad01fea7b 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -21,7 +21,7 @@
21 "Programming Languages" 21 "Programming Languages"
22 ], 22 ],
23 "engines": { 23 "engines": {
24 "vscode": "^1.51.0" 24 "vscode": "^1.52.0"
25 }, 25 },
26 "enableProposedApi": true, 26 "enableProposedApi": true,
27 "scripts": { 27 "scripts": {
@@ -36,7 +36,7 @@
36 }, 36 },
37 "dependencies": { 37 "dependencies": {
38 "node-fetch": "^2.6.1", 38 "node-fetch": "^2.6.1",
39 "vscode-languageclient": "7.0.0-next.14" 39 "vscode-languageclient": "7.0.0"
40 }, 40 },
41 "devDependencies": { 41 "devDependencies": {
42 "@rollup/plugin-commonjs": "^17.0.0", 42 "@rollup/plugin-commonjs": "^17.0.0",
@@ -45,7 +45,7 @@
45 "@types/mocha": "^8.0.4", 45 "@types/mocha": "^8.0.4",
46 "@types/node": "~12.12.6", 46 "@types/node": "~12.12.6",
47 "@types/node-fetch": "^2.5.7", 47 "@types/node-fetch": "^2.5.7",
48 "@types/vscode": "^1.51.0", 48 "@types/vscode": "^1.52.0",
49 "@typescript-eslint/eslint-plugin": "^4.9.0", 49 "@typescript-eslint/eslint-plugin": "^4.9.0",
50 "@typescript-eslint/parser": "^4.9.0", 50 "@typescript-eslint/parser": "^4.9.0",
51 "eslint": "^7.15.0", 51 "eslint": "^7.15.0",
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index 2ef956485..78a0b54ba 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -15,8 +15,8 @@ flate2 = "1.0"
15pico-args = "0.3.1" 15pico-args = "0.3.1"
16proc-macro2 = "1.0.8" 16proc-macro2 = "1.0.8"
17quote = "1.0.2" 17quote = "1.0.2"
18ungrammar = "1.1.3" 18ungrammar = "1.4"
19walkdir = "2.3.1" 19walkdir = "2.3.1"
20write-json = "0.1.0" 20write-json = "0.1.0"
21xshell = "0.1" 21xshell = "0.1"
22# Avoid adding more dependencies to this crate 22# Avoid adding more dependencies to this crate
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 72a4c10f5..a69ced5cc 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -76,7 +76,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
76 "ERROR", 76 "ERROR",
77 "IDENT", 77 "IDENT",
78 "WHITESPACE", 78 "WHITESPACE",
79 "LIFETIME", 79 "LIFETIME_IDENT",
80 "COMMENT", 80 "COMMENT",
81 "SHEBANG", 81 "SHEBANG",
82 "L_DOLLAR", 82 "L_DOLLAR",
@@ -202,6 +202,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
202 "TYPE_PARAM", 202 "TYPE_PARAM",
203 "CONST_PARAM", 203 "CONST_PARAM",
204 "GENERIC_ARG_LIST", 204 "GENERIC_ARG_LIST",
205 "LIFETIME",
205 "LIFETIME_ARG", 206 "LIFETIME_ARG",
206 "TYPE_ARG", 207 "TYPE_ARG",
207 "ASSOC_TYPE_ARG", 208 "ASSOC_TYPE_ARG",
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index 44460effa..eb524d85a 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -380,7 +380,7 @@ fn generate_syntax_kinds(grammar: KindsSrc<'_>) -> Result<String> {
380 macro_rules! T { 380 macro_rules! T {
381 #([#punctuation_values] => { $crate::SyntaxKind::#punctuation };)* 381 #([#punctuation_values] => { $crate::SyntaxKind::#punctuation };)*
382 #([#all_keywords_idents] => { $crate::SyntaxKind::#all_keywords };)* 382 #([#all_keywords_idents] => { $crate::SyntaxKind::#all_keywords };)*
383 [lifetime] => { $crate::SyntaxKind::LIFETIME }; 383 [lifetime_ident] => { $crate::SyntaxKind::LIFETIME_IDENT };
384 [ident] => { $crate::SyntaxKind::IDENT }; 384 [ident] => { $crate::SyntaxKind::IDENT };
385 [shebang] => { $crate::SyntaxKind::SHEBANG }; 385 [shebang] => { $crate::SyntaxKind::SHEBANG };
386 } 386 }