aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/assists/src/handlers/extract_struct_from_enum_variant.rs8
-rw-r--r--crates/assists/src/handlers/fill_match_arms.rs2
-rw-r--r--crates/assists/src/handlers/fix_visibility.rs2
-rw-r--r--crates/completion/src/completions.rs10
-rw-r--r--crates/completion/src/completions/pattern.rs2
-rw-r--r--crates/completion/src/render.rs9
-rw-r--r--crates/completion/src/render/enum_variant.rs26
-rw-r--r--crates/hir/src/attrs.rs6
-rw-r--r--crates/hir/src/code_model.rs45
-rw-r--r--crates/hir/src/from_id.rs23
-rw-r--r--crates/hir/src/has_source.rs6
-rw-r--r--crates/hir/src/lib.rs6
-rw-r--r--crates/hir/src/semantics.rs4
-rw-r--r--crates/hir/src/source_analyzer.rs18
-rw-r--r--crates/hir_def/src/generics.rs37
-rw-r--r--crates/hir_ty/src/lower.rs18
-rw-r--r--crates/hir_ty/src/utils.rs9
-rw-r--r--crates/ide/src/diagnostics/fixes.rs2
-rw-r--r--crates/ide/src/display/navigation_target.rs4
-rw-r--r--crates/ide/src/doc_links.rs4
-rw-r--r--crates/ide/src/goto_definition.rs28
-rw-r--r--crates/ide/src/hover.rs4
-rw-r--r--crates/ide/src/runnables.rs2
-rw-r--r--crates/ide/src/syntax_highlighting.rs2
-rw-r--r--crates/ide_db/src/defs.rs4
-rw-r--r--crates/ide_db/src/search.rs2
-rw-r--r--crates/mbe/src/mbe_expander/transcriber.rs2
-rw-r--r--crates/mbe/src/parser.rs4
-rw-r--r--crates/mbe/src/syntax_bridge.rs3
-rw-r--r--crates/mbe/src/tests.rs24
-rw-r--r--crates/parser/src/grammar.rs2
-rw-r--r--crates/parser/src/lib.rs2
32 files changed, 194 insertions, 126 deletions
diff --git a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs
index 2e56bd7ff..030b9cd0c 100644
--- a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -1,7 +1,7 @@
1use std::iter; 1use std::iter;
2 2
3use either::Either; 3use either::Either;
4use hir::{AsName, EnumVariant, Module, ModuleDef, Name}; 4use hir::{AsName, Module, ModuleDef, Name, Variant};
5use ide_db::helpers::{ 5use ide_db::helpers::{
6 insert_use::{insert_use, ImportScope}, 6 insert_use::{insert_use, ImportScope},
7 mod_path_to_ast, 7 mod_path_to_ast,
@@ -53,7 +53,7 @@ pub(crate) fn extract_struct_from_enum_variant(
53 let variant_hir_name = variant_hir.name(ctx.db()); 53 let variant_hir_name = variant_hir.name(ctx.db());
54 let enum_module_def = ModuleDef::from(enum_hir); 54 let enum_module_def = ModuleDef::from(enum_hir);
55 let usages = 55 let usages =
56 Definition::ModuleDef(ModuleDef::EnumVariant(variant_hir)).usages(&ctx.sema).all(); 56 Definition::ModuleDef(ModuleDef::Variant(variant_hir)).usages(&ctx.sema).all();
57 57
58 let mut visited_modules_set = FxHashSet::default(); 58 let mut visited_modules_set = FxHashSet::default();
59 let current_module = enum_hir.module(ctx.db()); 59 let current_module = enum_hir.module(ctx.db());
@@ -109,7 +109,7 @@ fn extract_field_list_if_applicable(
109 } 109 }
110} 110}
111 111
112fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &EnumVariant) -> bool { 112fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &Variant) -> bool {
113 variant 113 variant
114 .parent_enum(db) 114 .parent_enum(db)
115 .module(db) 115 .module(db)
@@ -119,7 +119,7 @@ fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &En
119 // only check type-namespace 119 // only check type-namespace
120 hir::ScopeDef::ModuleDef(def) => matches!(def, 120 hir::ScopeDef::ModuleDef(def) => matches!(def,
121 ModuleDef::Module(_) | ModuleDef::Adt(_) | 121 ModuleDef::Module(_) | ModuleDef::Adt(_) |
122 ModuleDef::EnumVariant(_) | ModuleDef::Trait(_) | 122 ModuleDef::Variant(_) | ModuleDef::Trait(_) |
123 ModuleDef::TypeAlias(_) | ModuleDef::BuiltinType(_) 123 ModuleDef::TypeAlias(_) | ModuleDef::BuiltinType(_)
124 ), 124 ),
125 _ => false, 125 _ => false,
diff --git a/crates/assists/src/handlers/fill_match_arms.rs b/crates/assists/src/handlers/fill_match_arms.rs
index ef12ef0cf..cb60a3128 100644
--- a/crates/assists/src/handlers/fill_match_arms.rs
+++ b/crates/assists/src/handlers/fill_match_arms.rs
@@ -192,7 +192,7 @@ fn resolve_tuple_of_enum_def(
192 .collect() 192 .collect()
193} 193}
194 194
195fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> Option<ast::Pat> { 195fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::Variant) -> Option<ast::Pat> {
196 let path = mod_path_to_ast(&module.find_use_path(db, ModuleDef::from(var))?); 196 let path = mod_path_to_ast(&module.find_use_path(db, ModuleDef::from(var))?);
197 197
198 // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though 198 // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though
diff --git a/crates/assists/src/handlers/fix_visibility.rs b/crates/assists/src/handlers/fix_visibility.rs
index c86720787..8558a8ff0 100644
--- a/crates/assists/src/handlers/fix_visibility.rs
+++ b/crates/assists/src/handlers/fix_visibility.rs
@@ -201,7 +201,7 @@ fn target_data_for_def(
201 (vis_offset(syntax), in_file_source.value.visibility(), syntax.text_range(), file_id) 201 (vis_offset(syntax), in_file_source.value.visibility(), syntax.text_range(), file_id)
202 } 202 }
203 // Enum variants can't be private, we can't modify builtin types 203 // Enum variants can't be private, we can't modify builtin types
204 hir::ModuleDef::EnumVariant(_) | hir::ModuleDef::BuiltinType(_) => return None, 204 hir::ModuleDef::Variant(_) | hir::ModuleDef::BuiltinType(_) => return None,
205 }; 205 };
206 206
207 Some((offset, current_visibility, target, target_file, target_name)) 207 Some((offset, current_visibility, target, target_file, target_name))
diff --git a/crates/completion/src/completions.rs b/crates/completion/src/completions.rs
index 9b7d6c580..1ef6b5f48 100644
--- a/crates/completion/src/completions.rs
+++ b/crates/completion/src/completions.rs
@@ -19,7 +19,7 @@ use hir::{ModPath, ScopeDef, Type};
19use crate::{ 19use crate::{
20 item::Builder, 20 item::Builder,
21 render::{ 21 render::{
22 const_::render_const, enum_variant::render_enum_variant, function::render_fn, 22 const_::render_const, enum_variant::render_variant, function::render_fn,
23 macro_::render_macro, render_field, render_resolution, render_tuple_field, 23 macro_::render_macro, render_field, render_resolution, render_tuple_field,
24 type_alias::render_type_alias, RenderContext, 24 type_alias::render_type_alias, RenderContext,
25 }, 25 },
@@ -120,20 +120,20 @@ impl Completions {
120 pub(crate) fn add_qualified_enum_variant( 120 pub(crate) fn add_qualified_enum_variant(
121 &mut self, 121 &mut self,
122 ctx: &CompletionContext, 122 ctx: &CompletionContext,
123 variant: hir::EnumVariant, 123 variant: hir::Variant,
124 path: ModPath, 124 path: ModPath,
125 ) { 125 ) {
126 let item = render_enum_variant(RenderContext::new(ctx), None, None, variant, Some(path)); 126 let item = render_variant(RenderContext::new(ctx), None, None, variant, Some(path));
127 self.add(item); 127 self.add(item);
128 } 128 }
129 129
130 pub(crate) fn add_enum_variant( 130 pub(crate) fn add_enum_variant(
131 &mut self, 131 &mut self,
132 ctx: &CompletionContext, 132 ctx: &CompletionContext,
133 variant: hir::EnumVariant, 133 variant: hir::Variant,
134 local_name: Option<String>, 134 local_name: Option<String>,
135 ) { 135 ) {
136 let item = render_enum_variant(RenderContext::new(ctx), None, local_name, variant, None); 136 let item = render_variant(RenderContext::new(ctx), None, local_name, variant, None);
137 self.add(item); 137 self.add(item);
138 } 138 }
139} 139}
diff --git a/crates/completion/src/completions/pattern.rs b/crates/completion/src/completions/pattern.rs
index 0c98e4412..4d56731ec 100644
--- a/crates/completion/src/completions/pattern.rs
+++ b/crates/completion/src/completions/pattern.rs
@@ -23,7 +23,7 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
23 def, 23 def,
24 hir::ModuleDef::Adt(hir::Adt::Enum(..)) 24 hir::ModuleDef::Adt(hir::Adt::Enum(..))
25 | hir::ModuleDef::Adt(hir::Adt::Struct(..)) 25 | hir::ModuleDef::Adt(hir::Adt::Struct(..))
26 | hir::ModuleDef::EnumVariant(..) 26 | hir::ModuleDef::Variant(..)
27 | hir::ModuleDef::Const(..) 27 | hir::ModuleDef::Const(..)
28 | hir::ModuleDef::Module(..) 28 | hir::ModuleDef::Module(..)
29 ) 29 )
diff --git a/crates/completion/src/render.rs b/crates/completion/src/render.rs
index b940388df..1092a4825 100644
--- a/crates/completion/src/render.rs
+++ b/crates/completion/src/render.rs
@@ -19,7 +19,7 @@ use crate::{
19 CompletionKind, CompletionScore, 19 CompletionKind, CompletionScore,
20}; 20};
21 21
22use crate::render::{enum_variant::render_enum_variant, function::render_fn, macro_::render_macro}; 22use crate::render::{enum_variant::render_variant, function::render_fn, macro_::render_macro};
23 23
24pub(crate) fn render_field<'a>( 24pub(crate) fn render_field<'a>(
25 ctx: RenderContext<'a>, 25 ctx: RenderContext<'a>,
@@ -159,9 +159,8 @@ impl<'a> Render<'a> {
159 let item = render_fn(self.ctx, import_to_add, Some(local_name), *func); 159 let item = render_fn(self.ctx, import_to_add, Some(local_name), *func);
160 return Some(item); 160 return Some(item);
161 } 161 }
162 ScopeDef::ModuleDef(EnumVariant(var)) => { 162 ScopeDef::ModuleDef(Variant(var)) => {
163 let item = 163 let item = render_variant(self.ctx, import_to_add, Some(local_name), *var, None);
164 render_enum_variant(self.ctx, import_to_add, Some(local_name), *var, None);
165 return Some(item); 164 return Some(item);
166 } 165 }
167 ScopeDef::MacroDef(mac) => { 166 ScopeDef::MacroDef(mac) => {
@@ -257,7 +256,7 @@ impl<'a> Render<'a> {
257 match resolution { 256 match resolution {
258 ScopeDef::ModuleDef(Module(it)) => it.docs(self.ctx.db()), 257 ScopeDef::ModuleDef(Module(it)) => it.docs(self.ctx.db()),
259 ScopeDef::ModuleDef(Adt(it)) => it.docs(self.ctx.db()), 258 ScopeDef::ModuleDef(Adt(it)) => it.docs(self.ctx.db()),
260 ScopeDef::ModuleDef(EnumVariant(it)) => it.docs(self.ctx.db()), 259 ScopeDef::ModuleDef(Variant(it)) => it.docs(self.ctx.db()),
261 ScopeDef::ModuleDef(Const(it)) => it.docs(self.ctx.db()), 260 ScopeDef::ModuleDef(Const(it)) => it.docs(self.ctx.db()),
262 ScopeDef::ModuleDef(Static(it)) => it.docs(self.ctx.db()), 261 ScopeDef::ModuleDef(Static(it)) => it.docs(self.ctx.db()),
263 ScopeDef::ModuleDef(Trait(it)) => it.docs(self.ctx.db()), 262 ScopeDef::ModuleDef(Trait(it)) => it.docs(self.ctx.db()),
diff --git a/crates/completion/src/render/enum_variant.rs b/crates/completion/src/render/enum_variant.rs
index 8e0fea6c0..7176fd9b3 100644
--- a/crates/completion/src/render/enum_variant.rs
+++ b/crates/completion/src/render/enum_variant.rs
@@ -9,35 +9,35 @@ use crate::{
9 render::{builder_ext::Params, RenderContext}, 9 render::{builder_ext::Params, RenderContext},
10}; 10};
11 11
12pub(crate) fn render_enum_variant<'a>( 12pub(crate) fn render_variant<'a>(
13 ctx: RenderContext<'a>, 13 ctx: RenderContext<'a>,
14 import_to_add: Option<ImportEdit>, 14 import_to_add: Option<ImportEdit>,
15 local_name: Option<String>, 15 local_name: Option<String>,
16 variant: hir::EnumVariant, 16 variant: hir::Variant,
17 path: Option<ModPath>, 17 path: Option<ModPath>,
18) -> CompletionItem { 18) -> CompletionItem {
19 let _p = profile::span("render_enum_variant"); 19 let _p = profile::span("render_enum_variant");
20 EnumVariantRender::new(ctx, local_name, variant, path).render(import_to_add) 20 EnumRender::new(ctx, local_name, variant, path).render(import_to_add)
21} 21}
22 22
23#[derive(Debug)] 23#[derive(Debug)]
24struct EnumVariantRender<'a> { 24struct EnumRender<'a> {
25 ctx: RenderContext<'a>, 25 ctx: RenderContext<'a>,
26 name: String, 26 name: String,
27 variant: hir::EnumVariant, 27 variant: hir::Variant,
28 path: Option<ModPath>, 28 path: Option<ModPath>,
29 qualified_name: String, 29 qualified_name: String,
30 short_qualified_name: String, 30 short_qualified_name: String,
31 variant_kind: StructKind, 31 variant_kind: StructKind,
32} 32}
33 33
34impl<'a> EnumVariantRender<'a> { 34impl<'a> EnumRender<'a> {
35 fn new( 35 fn new(
36 ctx: RenderContext<'a>, 36 ctx: RenderContext<'a>,
37 local_name: Option<String>, 37 local_name: Option<String>,
38 variant: hir::EnumVariant, 38 variant: hir::Variant,
39 path: Option<ModPath>, 39 path: Option<ModPath>,
40 ) -> EnumVariantRender<'a> { 40 ) -> EnumRender<'a> {
41 let name = local_name.unwrap_or_else(|| variant.name(ctx.db()).to_string()); 41 let name = local_name.unwrap_or_else(|| variant.name(ctx.db()).to_string());
42 let variant_kind = variant.kind(ctx.db()); 42 let variant_kind = variant.kind(ctx.db());
43 43
@@ -51,15 +51,7 @@ impl<'a> EnumVariantRender<'a> {
51 None => (name.to_string(), name.to_string()), 51 None => (name.to_string(), name.to_string()),
52 }; 52 };
53 53
54 EnumVariantRender { 54 EnumRender { ctx, name, variant, path, qualified_name, short_qualified_name, variant_kind }
55 ctx,
56 name,
57 variant,
58 path,
59 qualified_name,
60 short_qualified_name,
61 variant_kind,
62 }
63 } 55 }
64 56
65 fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem { 57 fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem {
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
index 1f2ee2580..d32ce37ed 100644
--- a/crates/hir/src/attrs.rs
+++ b/crates/hir/src/attrs.rs
@@ -10,8 +10,8 @@ use hir_ty::db::HirDatabase;
10use syntax::ast; 10use syntax::ast;
11 11
12use crate::{ 12use crate::{
13 Adt, Const, Enum, EnumVariant, Field, Function, MacroDef, Module, ModuleDef, Static, Struct, 13 Adt, Const, Enum, Field, Function, MacroDef, Module, ModuleDef, Static, Struct, Trait,
14 Trait, TypeAlias, Union, 14 TypeAlias, Union, Variant,
15}; 15};
16 16
17pub trait HasAttrs { 17pub trait HasAttrs {
@@ -53,7 +53,7 @@ macro_rules! impl_has_attrs {
53 53
54impl_has_attrs![ 54impl_has_attrs![
55 (Field, FieldId), 55 (Field, FieldId),
56 (EnumVariant, EnumVariantId), 56 (Variant, EnumVariantId),
57 (Static, StaticId), 57 (Static, StaticId),
58 (Const, ConstId), 58 (Const, ConstId),
59 (Trait, TraitId), 59 (Trait, TraitId),
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index 3248f6d20..73ca6ba9f 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -161,7 +161,7 @@ pub enum ModuleDef {
161 Function(Function), 161 Function(Function),
162 Adt(Adt), 162 Adt(Adt),
163 // Can't be directly declared, but can be imported. 163 // Can't be directly declared, but can be imported.
164 EnumVariant(EnumVariant), 164 Variant(Variant),
165 Const(Const), 165 Const(Const),
166 Static(Static), 166 Static(Static),
167 Trait(Trait), 167 Trait(Trait),
@@ -172,7 +172,7 @@ impl_from!(
172 Module, 172 Module,
173 Function, 173 Function,
174 Adt(Struct, Enum, Union), 174 Adt(Struct, Enum, Union),
175 EnumVariant, 175 Variant,
176 Const, 176 Const,
177 Static, 177 Static,
178 Trait, 178 Trait,
@@ -186,7 +186,7 @@ impl From<VariantDef> for ModuleDef {
186 match var { 186 match var {
187 VariantDef::Struct(t) => Adt::from(t).into(), 187 VariantDef::Struct(t) => Adt::from(t).into(),
188 VariantDef::Union(t) => Adt::from(t).into(), 188 VariantDef::Union(t) => Adt::from(t).into(),
189 VariantDef::EnumVariant(t) => t.into(), 189 VariantDef::Variant(t) => t.into(),
190 } 190 }
191 } 191 }
192} 192}
@@ -197,7 +197,7 @@ impl ModuleDef {
197 ModuleDef::Module(it) => it.parent(db), 197 ModuleDef::Module(it) => it.parent(db),
198 ModuleDef::Function(it) => Some(it.module(db)), 198 ModuleDef::Function(it) => Some(it.module(db)),
199 ModuleDef::Adt(it) => Some(it.module(db)), 199 ModuleDef::Adt(it) => Some(it.module(db)),
200 ModuleDef::EnumVariant(it) => Some(it.module(db)), 200 ModuleDef::Variant(it) => Some(it.module(db)),
201 ModuleDef::Const(it) => Some(it.module(db)), 201 ModuleDef::Const(it) => Some(it.module(db)),
202 ModuleDef::Static(it) => Some(it.module(db)), 202 ModuleDef::Static(it) => Some(it.module(db)),
203 ModuleDef::Trait(it) => Some(it.module(db)), 203 ModuleDef::Trait(it) => Some(it.module(db)),
@@ -221,7 +221,7 @@ impl ModuleDef {
221 ModuleDef::Module(it) => it.parent(db)?, 221 ModuleDef::Module(it) => it.parent(db)?,
222 ModuleDef::Function(it) => return Some(it.visibility(db)), 222 ModuleDef::Function(it) => return Some(it.visibility(db)),
223 ModuleDef::Adt(it) => it.module(db), 223 ModuleDef::Adt(it) => it.module(db),
224 ModuleDef::EnumVariant(it) => { 224 ModuleDef::Variant(it) => {
225 let parent = it.parent_enum(db); 225 let parent = it.parent_enum(db);
226 let module = it.module(db); 226 let module = it.module(db);
227 return module.visibility_of(db, &ModuleDef::Adt(Adt::Enum(parent))); 227 return module.visibility_of(db, &ModuleDef::Adt(Adt::Enum(parent)));
@@ -241,7 +241,7 @@ impl ModuleDef {
241 ModuleDef::Adt(it) => Some(it.name(db)), 241 ModuleDef::Adt(it) => Some(it.name(db)),
242 ModuleDef::Trait(it) => Some(it.name(db)), 242 ModuleDef::Trait(it) => Some(it.name(db)),
243 ModuleDef::Function(it) => Some(it.name(db)), 243 ModuleDef::Function(it) => Some(it.name(db)),
244 ModuleDef::EnumVariant(it) => Some(it.name(db)), 244 ModuleDef::Variant(it) => Some(it.name(db)),
245 ModuleDef::TypeAlias(it) => Some(it.name(db)), 245 ModuleDef::TypeAlias(it) => Some(it.name(db)),
246 ModuleDef::Module(it) => it.name(db), 246 ModuleDef::Module(it) => it.name(db),
247 ModuleDef::Const(it) => it.name(db), 247 ModuleDef::Const(it) => it.name(db),
@@ -455,7 +455,7 @@ impl Field {
455 let generic_def_id: GenericDefId = match self.parent { 455 let generic_def_id: GenericDefId = match self.parent {
456 VariantDef::Struct(it) => it.id.into(), 456 VariantDef::Struct(it) => it.id.into(),
457 VariantDef::Union(it) => it.id.into(), 457 VariantDef::Union(it) => it.id.into(),
458 VariantDef::EnumVariant(it) => it.parent.id.into(), 458 VariantDef::Variant(it) => it.parent.id.into(),
459 }; 459 };
460 let substs = Substs::type_params(db, generic_def_id); 460 let substs = Substs::type_params(db, generic_def_id);
461 let ty = db.field_types(var_id)[self.id].clone().subst(&substs); 461 let ty = db.field_types(var_id)[self.id].clone().subst(&substs);
@@ -566,12 +566,8 @@ impl Enum {
566 db.enum_data(self.id).name.clone() 566 db.enum_data(self.id).name.clone()
567 } 567 }
568 568
569 pub fn variants(self, db: &dyn HirDatabase) -> Vec<EnumVariant> { 569 pub fn variants(self, db: &dyn HirDatabase) -> Vec<Variant> {
570 db.enum_data(self.id) 570 db.enum_data(self.id).variants.iter().map(|(id, _)| Variant { parent: self, id }).collect()
571 .variants
572 .iter()
573 .map(|(id, _)| EnumVariant { parent: self, id })
574 .collect()
575 } 571 }
576 572
577 pub fn ty(self, db: &dyn HirDatabase) -> Type { 573 pub fn ty(self, db: &dyn HirDatabase) -> Type {
@@ -580,12 +576,12 @@ impl Enum {
580} 576}
581 577
582#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 578#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
583pub struct EnumVariant { 579pub struct Variant {
584 pub(crate) parent: Enum, 580 pub(crate) parent: Enum,
585 pub(crate) id: LocalEnumVariantId, 581 pub(crate) id: LocalEnumVariantId,
586} 582}
587 583
588impl EnumVariant { 584impl Variant {
589 pub fn module(self, db: &dyn HirDatabase) -> Module { 585 pub fn module(self, db: &dyn HirDatabase) -> Module {
590 self.parent.module(db) 586 self.parent.module(db)
591 } 587 }
@@ -662,16 +658,16 @@ impl Adt {
662pub enum VariantDef { 658pub enum VariantDef {
663 Struct(Struct), 659 Struct(Struct),
664 Union(Union), 660 Union(Union),
665 EnumVariant(EnumVariant), 661 Variant(Variant),
666} 662}
667impl_from!(Struct, Union, EnumVariant for VariantDef); 663impl_from!(Struct, Union, Variant for VariantDef);
668 664
669impl VariantDef { 665impl VariantDef {
670 pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { 666 pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
671 match self { 667 match self {
672 VariantDef::Struct(it) => it.fields(db), 668 VariantDef::Struct(it) => it.fields(db),
673 VariantDef::Union(it) => it.fields(db), 669 VariantDef::Union(it) => it.fields(db),
674 VariantDef::EnumVariant(it) => it.fields(db), 670 VariantDef::Variant(it) => it.fields(db),
675 } 671 }
676 } 672 }
677 673
@@ -679,7 +675,7 @@ impl VariantDef {
679 match self { 675 match self {
680 VariantDef::Struct(it) => it.module(db), 676 VariantDef::Struct(it) => it.module(db),
681 VariantDef::Union(it) => it.module(db), 677 VariantDef::Union(it) => it.module(db),
682 VariantDef::EnumVariant(it) => it.module(db), 678 VariantDef::Variant(it) => it.module(db),
683 } 679 }
684 } 680 }
685 681
@@ -687,7 +683,7 @@ impl VariantDef {
687 match self { 683 match self {
688 VariantDef::Struct(s) => s.name(db), 684 VariantDef::Struct(s) => s.name(db),
689 VariantDef::Union(u) => u.name(db), 685 VariantDef::Union(u) => u.name(db),
690 VariantDef::EnumVariant(e) => e.name(db), 686 VariantDef::Variant(e) => e.name(db),
691 } 687 }
692 } 688 }
693 689
@@ -695,7 +691,7 @@ impl VariantDef {
695 match self { 691 match self {
696 VariantDef::Struct(it) => it.variant_data(db), 692 VariantDef::Struct(it) => it.variant_data(db),
697 VariantDef::Union(it) => it.variant_data(db), 693 VariantDef::Union(it) => it.variant_data(db),
698 VariantDef::EnumVariant(it) => it.variant_data(db), 694 VariantDef::Variant(it) => it.variant_data(db),
699 } 695 }
700 } 696 }
701} 697}
@@ -1095,7 +1091,7 @@ pub enum GenericDef {
1095 Impl(Impl), 1091 Impl(Impl),
1096 // enum variants cannot have generics themselves, but their parent enums 1092 // enum variants cannot have generics themselves, but their parent enums
1097 // can, and this makes some code easier to write 1093 // can, and this makes some code easier to write
1098 EnumVariant(EnumVariant), 1094 Variant(Variant),
1099 // consts can have type parameters from their parents (i.e. associated consts of traits) 1095 // consts can have type parameters from their parents (i.e. associated consts of traits)
1100 Const(Const), 1096 Const(Const),
1101} 1097}
@@ -1105,7 +1101,7 @@ impl_from!(
1105 Trait, 1101 Trait,
1106 TypeAlias, 1102 TypeAlias,
1107 Impl, 1103 Impl,
1108 EnumVariant, 1104 Variant,
1109 Const 1105 Const
1110 for GenericDef 1106 for GenericDef
1111); 1107);
@@ -1272,7 +1268,6 @@ impl LifetimeParam {
1272 } 1268 }
1273} 1269}
1274 1270
1275// FIXME: rename from `ImplDef` to `Impl`
1276#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 1271#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1277pub struct Impl { 1272pub struct Impl {
1278 pub(crate) id: ImplId, 1273 pub(crate) id: ImplId,
@@ -1847,7 +1842,7 @@ pub struct Callable {
1847pub enum CallableKind { 1842pub enum CallableKind {
1848 Function(Function), 1843 Function(Function),
1849 TupleStruct(Struct), 1844 TupleStruct(Struct),
1850 TupleEnumVariant(EnumVariant), 1845 TupleEnumVariant(Variant),
1851 Closure, 1846 Closure,
1852} 1847}
1853 1848
diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs
index 8d0f84508..8e0c571b8 100644
--- a/crates/hir/src/from_id.rs
+++ b/crates/hir/src/from_id.rs
@@ -9,8 +9,7 @@ use hir_def::{
9}; 9};
10 10
11use crate::{ 11use crate::{
12 Adt, AssocItem, DefWithBody, EnumVariant, Field, GenericDef, Local, MacroDef, ModuleDef, 12 Adt, AssocItem, DefWithBody, Field, GenericDef, Local, MacroDef, ModuleDef, Variant, VariantDef,
13 VariantDef,
14}; 13};
15 14
16macro_rules! from_id { 15macro_rules! from_id {
@@ -65,14 +64,14 @@ impl From<Adt> for AdtId {
65 } 64 }
66} 65}
67 66
68impl From<EnumVariantId> for EnumVariant { 67impl From<EnumVariantId> for Variant {
69 fn from(id: EnumVariantId) -> Self { 68 fn from(id: EnumVariantId) -> Self {
70 EnumVariant { parent: id.parent.into(), id: id.local_id } 69 Variant { parent: id.parent.into(), id: id.local_id }
71 } 70 }
72} 71}
73 72
74impl From<EnumVariant> for EnumVariantId { 73impl From<Variant> for EnumVariantId {
75 fn from(def: EnumVariant) -> Self { 74 fn from(def: Variant) -> Self {
76 EnumVariantId { parent: def.parent.id, local_id: def.id } 75 EnumVariantId { parent: def.parent.id, local_id: def.id }
77 } 76 }
78} 77}
@@ -83,7 +82,7 @@ impl From<ModuleDefId> for ModuleDef {
83 ModuleDefId::ModuleId(it) => ModuleDef::Module(it.into()), 82 ModuleDefId::ModuleId(it) => ModuleDef::Module(it.into()),
84 ModuleDefId::FunctionId(it) => ModuleDef::Function(it.into()), 83 ModuleDefId::FunctionId(it) => ModuleDef::Function(it.into()),
85 ModuleDefId::AdtId(it) => ModuleDef::Adt(it.into()), 84 ModuleDefId::AdtId(it) => ModuleDef::Adt(it.into()),
86 ModuleDefId::EnumVariantId(it) => ModuleDef::EnumVariant(it.into()), 85 ModuleDefId::EnumVariantId(it) => ModuleDef::Variant(it.into()),
87 ModuleDefId::ConstId(it) => ModuleDef::Const(it.into()), 86 ModuleDefId::ConstId(it) => ModuleDef::Const(it.into()),
88 ModuleDefId::StaticId(it) => ModuleDef::Static(it.into()), 87 ModuleDefId::StaticId(it) => ModuleDef::Static(it.into()),
89 ModuleDefId::TraitId(it) => ModuleDef::Trait(it.into()), 88 ModuleDefId::TraitId(it) => ModuleDef::Trait(it.into()),
@@ -99,7 +98,7 @@ impl From<ModuleDef> for ModuleDefId {
99 ModuleDef::Module(it) => ModuleDefId::ModuleId(it.into()), 98 ModuleDef::Module(it) => ModuleDefId::ModuleId(it.into()),
100 ModuleDef::Function(it) => ModuleDefId::FunctionId(it.into()), 99 ModuleDef::Function(it) => ModuleDefId::FunctionId(it.into()),
101 ModuleDef::Adt(it) => ModuleDefId::AdtId(it.into()), 100 ModuleDef::Adt(it) => ModuleDefId::AdtId(it.into()),
102 ModuleDef::EnumVariant(it) => ModuleDefId::EnumVariantId(it.into()), 101 ModuleDef::Variant(it) => ModuleDefId::EnumVariantId(it.into()),
103 ModuleDef::Const(it) => ModuleDefId::ConstId(it.into()), 102 ModuleDef::Const(it) => ModuleDefId::ConstId(it.into()),
104 ModuleDef::Static(it) => ModuleDefId::StaticId(it.into()), 103 ModuleDef::Static(it) => ModuleDefId::StaticId(it.into()),
105 ModuleDef::Trait(it) => ModuleDefId::TraitId(it.into()), 104 ModuleDef::Trait(it) => ModuleDefId::TraitId(it.into()),
@@ -147,7 +146,7 @@ impl From<GenericDef> for GenericDefId {
147 GenericDef::Trait(it) => GenericDefId::TraitId(it.id), 146 GenericDef::Trait(it) => GenericDefId::TraitId(it.id),
148 GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id), 147 GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id),
149 GenericDef::Impl(it) => GenericDefId::ImplId(it.id), 148 GenericDef::Impl(it) => GenericDefId::ImplId(it.id),
150 GenericDef::EnumVariant(it) => { 149 GenericDef::Variant(it) => {
151 GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id }) 150 GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id })
152 } 151 }
153 GenericDef::Const(it) => GenericDefId::ConstId(it.id), 152 GenericDef::Const(it) => GenericDefId::ConstId(it.id),
@@ -164,7 +163,7 @@ impl From<GenericDefId> for GenericDef {
164 GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), 163 GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()),
165 GenericDefId::ImplId(it) => GenericDef::Impl(it.into()), 164 GenericDefId::ImplId(it) => GenericDef::Impl(it.into()),
166 GenericDefId::EnumVariantId(it) => { 165 GenericDefId::EnumVariantId(it) => {
167 GenericDef::EnumVariant(EnumVariant { parent: it.parent.into(), id: it.local_id }) 166 GenericDef::Variant(Variant { parent: it.parent.into(), id: it.local_id })
168 } 167 }
169 GenericDefId::ConstId(it) => GenericDef::Const(it.into()), 168 GenericDefId::ConstId(it) => GenericDef::Const(it.into()),
170 } 169 }
@@ -185,7 +184,7 @@ impl From<VariantId> for VariantDef {
185 fn from(def: VariantId) -> Self { 184 fn from(def: VariantId) -> Self {
186 match def { 185 match def {
187 VariantId::StructId(it) => VariantDef::Struct(it.into()), 186 VariantId::StructId(it) => VariantDef::Struct(it.into()),
188 VariantId::EnumVariantId(it) => VariantDef::EnumVariant(it.into()), 187 VariantId::EnumVariantId(it) => VariantDef::Variant(it.into()),
189 VariantId::UnionId(it) => VariantDef::Union(it.into()), 188 VariantId::UnionId(it) => VariantDef::Union(it.into()),
190 } 189 }
191 } 190 }
@@ -195,7 +194,7 @@ impl From<VariantDef> for VariantId {
195 fn from(def: VariantDef) -> Self { 194 fn from(def: VariantDef) -> Self {
196 match def { 195 match def {
197 VariantDef::Struct(it) => VariantId::StructId(it.id), 196 VariantDef::Struct(it) => VariantId::StructId(it.id),
198 VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()), 197 VariantDef::Variant(it) => VariantId::EnumVariantId(it.into()),
199 VariantDef::Union(it) => VariantId::UnionId(it.id), 198 VariantDef::Union(it) => VariantId::UnionId(it.id),
200 } 199 }
201 } 200 }
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs
index c5b81b252..0dc07c33e 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, Impl, LifetimeParam, 13 db::HirDatabase, Const, Enum, Field, FieldSource, Function, Impl, LifetimeParam, MacroDef,
14 MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, 14 Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant,
15}; 15};
16 16
17pub trait HasSource { 17pub trait HasSource {
@@ -73,7 +73,7 @@ impl HasSource for Enum {
73 self.id.lookup(db.upcast()).source(db.upcast()) 73 self.id.lookup(db.upcast()).source(db.upcast())
74 } 74 }
75} 75}
76impl HasSource for EnumVariant { 76impl HasSource for Variant {
77 type Ast = ast::Variant; 77 type Ast = ast::Variant;
78 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Variant> { 78 fn source(self, db: &dyn HirDatabase) -> InFile<ast::Variant> {
79 self.parent.id.child_source(db.upcast()).map(|map| map[self.id].clone()) 79 self.parent.id.child_source(db.upcast()).map(|map| map[self.id].clone())
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 3f4f8d8e4..bdd270c58 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -34,9 +34,9 @@ pub use crate::{
34 attrs::{HasAttrs, Namespace}, 34 attrs::{HasAttrs, Namespace},
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, Field, FieldSource, Function, GenericDef,
38 GenericDef, HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module, ModuleDef, 38 HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module, ModuleDef, ScopeDef, Static,
39 ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, 39 Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef,
40 }, 40 },
41 has_source::HasSource, 41 has_source::HasSource,
42 semantics::{PathResolution, Semantics, SemanticsScope}, 42 semantics::{PathResolution, Semantics, SemanticsScope},
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 83ec91f58..25ebf73d8 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -51,7 +51,7 @@ impl PathResolution {
51 Some(TypeNs::BuiltinType(*builtin)) 51 Some(TypeNs::BuiltinType(*builtin))
52 } 52 }
53 PathResolution::Def(ModuleDef::Const(_)) 53 PathResolution::Def(ModuleDef::Const(_))
54 | PathResolution::Def(ModuleDef::EnumVariant(_)) 54 | PathResolution::Def(ModuleDef::Variant(_))
55 | PathResolution::Def(ModuleDef::Function(_)) 55 | PathResolution::Def(ModuleDef::Function(_))
56 | PathResolution::Def(ModuleDef::Module(_)) 56 | PathResolution::Def(ModuleDef::Module(_))
57 | PathResolution::Def(ModuleDef::Static(_)) 57 | PathResolution::Def(ModuleDef::Static(_))
@@ -715,7 +715,7 @@ to_def_impls![
715 (crate::Function, ast::Fn, fn_to_def), 715 (crate::Function, ast::Fn, fn_to_def),
716 (crate::Field, ast::RecordField, record_field_to_def), 716 (crate::Field, ast::RecordField, record_field_to_def),
717 (crate::Field, ast::TupleField, tuple_field_to_def), 717 (crate::Field, ast::TupleField, tuple_field_to_def),
718 (crate::EnumVariant, ast::Variant, enum_variant_to_def), 718 (crate::Variant, ast::Variant, enum_variant_to_def),
719 (crate::TypeParam, ast::TypeParam, type_param_to_def), 719 (crate::TypeParam, ast::TypeParam, type_param_to_def),
720 (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), 720 (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def),
721 (crate::MacroDef, ast::MacroRules, macro_rules_to_def), 721 (crate::MacroDef, ast::MacroRules, macro_rules_to_def),
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index bf0c959fe..bddc49c05 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -28,8 +28,8 @@ use syntax::{
28}; 28};
29 29
30use crate::{ 30use crate::{
31 db::HirDatabase, semantics::PathResolution, Adt, Const, EnumVariant, Field, Function, Local, 31 db::HirDatabase, semantics::PathResolution, Adt, Const, Field, Function, Local, MacroDef,
32 MacroDef, ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, 32 ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Variant,
33}; 33};
34use base_db::CrateId; 34use base_db::CrateId;
35 35
@@ -230,7 +230,7 @@ impl SourceAnalyzer {
230 if let Some(VariantId::EnumVariantId(variant)) = 230 if let Some(VariantId::EnumVariantId(variant)) =
231 self.infer.as_ref()?.variant_resolution_for_expr(expr_id) 231 self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
232 { 232 {
233 return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into()))); 233 return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
234 } 234 }
235 } 235 }
236 236
@@ -242,7 +242,7 @@ impl SourceAnalyzer {
242 if let Some(VariantId::EnumVariantId(variant)) = 242 if let Some(VariantId::EnumVariantId(variant)) =
243 self.infer.as_ref()?.variant_resolution_for_pat(pat_id) 243 self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
244 { 244 {
245 return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into()))); 245 return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
246 } 246 }
247 } 247 }
248 248
@@ -251,7 +251,7 @@ impl SourceAnalyzer {
251 if let Some(VariantId::EnumVariantId(variant)) = 251 if let Some(VariantId::EnumVariantId(variant)) =
252 self.infer.as_ref()?.variant_resolution_for_expr(expr_id) 252 self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
253 { 253 {
254 return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into()))); 254 return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
255 } 255 }
256 } 256 }
257 257
@@ -260,7 +260,7 @@ impl SourceAnalyzer {
260 if let Some(VariantId::EnumVariantId(variant)) = 260 if let Some(VariantId::EnumVariantId(variant)) =
261 self.infer.as_ref()?.variant_resolution_for_pat(pat_id) 261 self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
262 { 262 {
263 return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into()))); 263 return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
264 } 264 }
265 } 265 }
266 266
@@ -459,7 +459,7 @@ pub(crate) fn resolve_hir_path(
459 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { 459 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
460 PathResolution::Def(Adt::from(it).into()) 460 PathResolution::Def(Adt::from(it).into())
461 } 461 }
462 TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), 462 TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
463 TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), 463 TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
464 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), 464 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()),
465 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), 465 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
@@ -477,7 +477,7 @@ pub(crate) fn resolve_hir_path(
477 ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), 477 ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()),
478 ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), 478 ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()),
479 ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), 479 ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()),
480 ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), 480 ValueNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
481 ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()), 481 ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()),
482 }; 482 };
483 Some(res) 483 Some(res)
@@ -526,7 +526,7 @@ fn resolve_hir_path_qualifier(
526 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), 526 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
527 TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), 527 TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }),
528 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => PathResolution::Def(Adt::from(it).into()), 528 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => PathResolution::Def(Adt::from(it).into()),
529 TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), 529 TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
530 TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), 530 TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
531 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), 531 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()),
532 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), 532 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs
index 41134d23b..bb8fca009 100644
--- a/crates/hir_def/src/generics.rs
+++ b/crates/hir_def/src/generics.rs
@@ -62,6 +62,7 @@ pub struct GenericParams {
62pub enum WherePredicate { 62pub enum WherePredicate {
63 TypeBound { target: WherePredicateTypeTarget, bound: TypeBound }, 63 TypeBound { target: WherePredicateTypeTarget, bound: TypeBound },
64 Lifetime { target: LifetimeRef, bound: LifetimeRef }, 64 Lifetime { target: LifetimeRef, bound: LifetimeRef },
65 ForLifetime { lifetimes: Box<[Name]>, target: WherePredicateTypeTarget, bound: TypeBound },
65} 66}
66 67
67#[derive(Clone, PartialEq, Eq, Debug)] 68#[derive(Clone, PartialEq, Eq, Debug)]
@@ -69,7 +70,6 @@ pub enum WherePredicateTypeTarget {
69 TypeRef(TypeRef), 70 TypeRef(TypeRef),
70 /// For desugared where predicates that can directly refer to a type param. 71 /// For desugared where predicates that can directly refer to a type param.
71 TypeParam(LocalTypeParamId), 72 TypeParam(LocalTypeParamId),
72 // FIXME: ForLifetime(Vec<LifetimeParamId>, TypeRef)
73} 73}
74 74
75#[derive(Default)] 75#[derive(Default)]
@@ -234,7 +234,7 @@ impl GenericParams {
234 for bound in 234 for bound in
235 node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) 235 node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds())
236 { 236 {
237 self.add_where_predicate_from_bound(lower_ctx, bound, target.clone()); 237 self.add_where_predicate_from_bound(lower_ctx, bound, None, target.clone());
238 } 238 }
239 } 239 }
240 240
@@ -279,8 +279,25 @@ impl GenericParams {
279 } else { 279 } else {
280 continue; 280 continue;
281 }; 281 };
282
283 let lifetimes: Option<Box<_>> = pred.generic_param_list().map(|param_list| {
284 // Higher-Ranked Trait Bounds
285 param_list
286 .lifetime_params()
287 .map(|lifetime_param| {
288 lifetime_param
289 .lifetime()
290 .map_or_else(Name::missing, |lt| Name::new_lifetime(&lt))
291 })
292 .collect()
293 });
282 for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { 294 for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) {
283 self.add_where_predicate_from_bound(lower_ctx, bound, target.clone()); 295 self.add_where_predicate_from_bound(
296 lower_ctx,
297 bound,
298 lifetimes.as_ref(),
299 target.clone(),
300 );
284 } 301 }
285 } 302 }
286 } 303 }
@@ -289,6 +306,7 @@ impl GenericParams {
289 &mut self, 306 &mut self,
290 lower_ctx: &LowerCtx, 307 lower_ctx: &LowerCtx,
291 bound: ast::TypeBound, 308 bound: ast::TypeBound,
309 hrtb_lifetimes: Option<&Box<[Name]>>,
292 target: Either<TypeRef, LifetimeRef>, 310 target: Either<TypeRef, LifetimeRef>,
293 ) { 311 ) {
294 if bound.question_mark_token().is_some() { 312 if bound.question_mark_token().is_some() {
@@ -297,9 +315,16 @@ impl GenericParams {
297 } 315 }
298 let bound = TypeBound::from_ast(lower_ctx, bound); 316 let bound = TypeBound::from_ast(lower_ctx, bound);
299 let predicate = match (target, bound) { 317 let predicate = match (target, bound) {
300 (Either::Left(type_ref), bound) => WherePredicate::TypeBound { 318 (Either::Left(type_ref), bound) => match hrtb_lifetimes {
301 target: WherePredicateTypeTarget::TypeRef(type_ref), 319 Some(hrtb_lifetimes) => WherePredicate::ForLifetime {
302 bound, 320 lifetimes: hrtb_lifetimes.clone(),
321 target: WherePredicateTypeTarget::TypeRef(type_ref),
322 bound,
323 },
324 None => WherePredicate::TypeBound {
325 target: WherePredicateTypeTarget::TypeRef(type_ref),
326 bound,
327 },
303 }, 328 },
304 (Either::Right(lifetime), TypeBound::Lifetime(bound)) => { 329 (Either::Right(lifetime), TypeBound::Lifetime(bound)) => {
305 WherePredicate::Lifetime { target: lifetime, bound } 330 WherePredicate::Lifetime { target: lifetime, bound }
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 8392cb770..8da56cd11 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -675,7 +675,8 @@ impl GenericPredicate {
675 where_predicate: &'a WherePredicate, 675 where_predicate: &'a WherePredicate,
676 ) -> impl Iterator<Item = GenericPredicate> + 'a { 676 ) -> impl Iterator<Item = GenericPredicate> + 'a {
677 match where_predicate { 677 match where_predicate {
678 WherePredicate::TypeBound { target, bound } => { 678 WherePredicate::ForLifetime { target, bound, .. }
679 | WherePredicate::TypeBound { target, bound } => {
679 let self_ty = match target { 680 let self_ty = match target {
680 WherePredicateTypeTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref), 681 WherePredicateTypeTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref),
681 WherePredicateTypeTarget::TypeParam(param_id) => { 682 WherePredicateTypeTarget::TypeParam(param_id) => {
@@ -888,14 +889,13 @@ pub(crate) fn generic_predicates_for_param_query(
888 .where_predicates_in_scope() 889 .where_predicates_in_scope()
889 // we have to filter out all other predicates *first*, before attempting to lower them 890 // we have to filter out all other predicates *first*, before attempting to lower them
890 .filter(|pred| match pred { 891 .filter(|pred| match pred {
891 WherePredicate::TypeBound { 892 WherePredicate::ForLifetime { target, .. }
892 target: WherePredicateTypeTarget::TypeRef(type_ref), 893 | WherePredicate::TypeBound { target, .. } => match target {
893 .. 894 WherePredicateTypeTarget::TypeRef(type_ref) => {
894 } => Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id), 895 Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id)
895 WherePredicate::TypeBound { 896 }
896 target: WherePredicateTypeTarget::TypeParam(local_id), 897 WherePredicateTypeTarget::TypeParam(local_id) => *local_id == param_id.local_id,
897 .. 898 },
898 } => *local_id == param_id.local_id,
899 WherePredicate::Lifetime { .. } => false, 899 WherePredicate::Lifetime { .. } => false,
900 }) 900 })
901 .flat_map(|pred| { 901 .flat_map(|pred| {
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index af880c065..65b79df0d 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -5,7 +5,9 @@ use std::sync::Arc;
5use hir_def::{ 5use hir_def::{
6 adt::VariantData, 6 adt::VariantData,
7 db::DefDatabase, 7 db::DefDatabase,
8 generics::{GenericParams, TypeParamData, TypeParamProvenance, WherePredicateTypeTarget}, 8 generics::{
9 GenericParams, TypeParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
10 },
9 path::Path, 11 path::Path,
10 resolver::{HasResolver, TypeNs}, 12 resolver::{HasResolver, TypeNs},
11 type_ref::TypeRef, 13 type_ref::TypeRef,
@@ -27,7 +29,8 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
27 .where_predicates 29 .where_predicates
28 .iter() 30 .iter()
29 .filter_map(|pred| match pred { 31 .filter_map(|pred| match pred {
30 hir_def::generics::WherePredicate::TypeBound { target, bound } => match target { 32 WherePredicate::ForLifetime { target, bound, .. }
33 | WherePredicate::TypeBound { target, bound } => match target {
31 WherePredicateTypeTarget::TypeRef(TypeRef::Path(p)) 34 WherePredicateTypeTarget::TypeRef(TypeRef::Path(p))
32 if p == &Path::from(name![Self]) => 35 if p == &Path::from(name![Self]) =>
33 { 36 {
@@ -38,7 +41,7 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
38 } 41 }
39 _ => None, 42 _ => None,
40 }, 43 },
41 hir_def::generics::WherePredicate::Lifetime { .. } => None, 44 WherePredicate::Lifetime { .. } => None,
42 }) 45 })
43 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) { 46 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) {
44 Some(TypeNs::TraitId(t)) => Some(t), 47 Some(TypeNs::TraitId(t)) => Some(t),
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs
index 13240672f..e8b896623 100644
--- a/crates/ide/src/diagnostics/fixes.rs
+++ b/crates/ide/src/diagnostics/fixes.rs
@@ -166,7 +166,7 @@ fn missing_record_expr_field_fix(
166 def_file_id = source.file_id; 166 def_file_id = source.file_id;
167 source.value.record_field_list()? 167 source.value.record_field_list()?
168 } 168 }
169 VariantDef::EnumVariant(e) => { 169 VariantDef::Variant(e) => {
170 module = e.module(sema.db); 170 module = e.module(sema.db);
171 let source = e.source(sema.db); 171 let source = e.source(sema.db);
172 def_file_id = source.file_id; 172 def_file_id = source.file_id;
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs
index 7d0514105..cd8ec54fa 100644
--- a/crates/ide/src/display/navigation_target.rs
+++ b/crates/ide/src/display/navigation_target.rs
@@ -233,7 +233,7 @@ impl TryToNav for hir::ModuleDef {
233 hir::ModuleDef::Module(it) => it.to_nav(db), 233 hir::ModuleDef::Module(it) => it.to_nav(db),
234 hir::ModuleDef::Function(it) => it.to_nav(db), 234 hir::ModuleDef::Function(it) => it.to_nav(db),
235 hir::ModuleDef::Adt(it) => it.to_nav(db), 235 hir::ModuleDef::Adt(it) => it.to_nav(db),
236 hir::ModuleDef::EnumVariant(it) => it.to_nav(db), 236 hir::ModuleDef::Variant(it) => it.to_nav(db),
237 hir::ModuleDef::Const(it) => it.to_nav(db), 237 hir::ModuleDef::Const(it) => it.to_nav(db),
238 hir::ModuleDef::Static(it) => it.to_nav(db), 238 hir::ModuleDef::Static(it) => it.to_nav(db),
239 hir::ModuleDef::Trait(it) => it.to_nav(db), 239 hir::ModuleDef::Trait(it) => it.to_nav(db),
@@ -262,7 +262,7 @@ impl ToNavFromAst for hir::Struct {
262impl ToNavFromAst for hir::Enum { 262impl ToNavFromAst for hir::Enum {
263 const KIND: SymbolKind = SymbolKind::Enum; 263 const KIND: SymbolKind = SymbolKind::Enum;
264} 264}
265impl ToNavFromAst for hir::EnumVariant { 265impl ToNavFromAst for hir::Variant {
266 const KIND: SymbolKind = SymbolKind::Variant; 266 const KIND: SymbolKind = SymbolKind::Variant;
267} 267}
268impl ToNavFromAst for hir::Union { 268impl ToNavFromAst for hir::Union {
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index 79c081cac..b61ea0b3e 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -181,7 +181,7 @@ fn rewrite_intra_doc_link(
181 ModuleDef::Module(it) => it.resolve_doc_path(db, link, ns), 181 ModuleDef::Module(it) => it.resolve_doc_path(db, link, ns),
182 ModuleDef::Function(it) => it.resolve_doc_path(db, link, ns), 182 ModuleDef::Function(it) => it.resolve_doc_path(db, link, ns),
183 ModuleDef::Adt(it) => it.resolve_doc_path(db, link, ns), 183 ModuleDef::Adt(it) => it.resolve_doc_path(db, link, ns),
184 ModuleDef::EnumVariant(it) => it.resolve_doc_path(db, link, ns), 184 ModuleDef::Variant(it) => it.resolve_doc_path(db, link, ns),
185 ModuleDef::Const(it) => it.resolve_doc_path(db, link, ns), 185 ModuleDef::Const(it) => it.resolve_doc_path(db, link, ns),
186 ModuleDef::Static(it) => it.resolve_doc_path(db, link, ns), 186 ModuleDef::Static(it) => it.resolve_doc_path(db, link, ns),
187 ModuleDef::Trait(it) => it.resolve_doc_path(db, link, ns), 187 ModuleDef::Trait(it) => it.resolve_doc_path(db, link, ns),
@@ -390,7 +390,7 @@ fn get_symbol_filename(db: &dyn HirDatabase, definition: &ModuleDef) -> Option<S
390 ModuleDef::TypeAlias(t) => format!("type.{}.html", t.name(db)), 390 ModuleDef::TypeAlias(t) => format!("type.{}.html", t.name(db)),
391 ModuleDef::BuiltinType(t) => format!("primitive.{}.html", t.as_name()), 391 ModuleDef::BuiltinType(t) => format!("primitive.{}.html", t.as_name()),
392 ModuleDef::Function(f) => format!("fn.{}.html", f.name(db)), 392 ModuleDef::Function(f) => format!("fn.{}.html", f.name(db)),
393 ModuleDef::EnumVariant(ev) => { 393 ModuleDef::Variant(ev) => {
394 format!("enum.{}.html#variant.{}", ev.parent_enum(db).name(db), ev.name(db)) 394 format!("enum.{}.html#variant.{}", ev.parent_enum(db).name(db), ev.name(db))
395 } 395 }
396 ModuleDef::Const(c) => format!("const.{}.html", c.name(db)?), 396 ModuleDef::Const(c) => format!("const.{}.html", c.name(db)?),
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 7a12e9965..431da5d9c 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1077,4 +1077,32 @@ fn foo<'foobar>(_: &'foobar ()) {
1077}"#, 1077}"#,
1078 ) 1078 )
1079 } 1079 }
1080
1081 #[test]
1082 #[ignore] // requires the HIR to somehow track these hrtb lifetimes
1083 fn goto_lifetime_hrtb() {
1084 check(
1085 r#"trait Foo<T> {}
1086fn foo<T>() where for<'a> T: Foo<&'a<|> (u8, u16)>, {}
1087 //^^
1088"#,
1089 );
1090 check(
1091 r#"trait Foo<T> {}
1092fn foo<T>() where for<'a<|>> T: Foo<&'a (u8, u16)>, {}
1093 //^^
1094"#,
1095 );
1096 }
1097
1098 #[test]
1099 #[ignore] // requires ForTypes to be implemented
1100 fn goto_lifetime_hrtb_for_type() {
1101 check(
1102 r#"trait Foo<T> {}
1103fn foo<T>() where T: for<'a> Foo<&'a<|> (u8, u16)>, {}
1104 //^^
1105"#,
1106 );
1107 }
1080} 1108}
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index b06fa5f15..52f993cc9 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -297,7 +297,7 @@ fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option<String>
297 AssocItemContainer::Trait(t) => Some(t.name(db)), 297 AssocItemContainer::Trait(t) => Some(t.name(db)),
298 AssocItemContainer::Impl(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::Variant(e) => Some(e.parent_enum(db).name(db)),
301 _ => None, 301 _ => None,
302 }, 302 },
303 _ => None, 303 _ => None,
@@ -355,7 +355,7 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> {
355 ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it, mod_path), 355 ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it, mod_path),
356 ModuleDef::Adt(Adt::Union(it)) => from_def_source(db, it, mod_path), 356 ModuleDef::Adt(Adt::Union(it)) => from_def_source(db, it, mod_path),
357 ModuleDef::Adt(Adt::Enum(it)) => from_def_source(db, it, mod_path), 357 ModuleDef::Adt(Adt::Enum(it)) => from_def_source(db, it, mod_path),
358 ModuleDef::EnumVariant(it) => from_def_source(db, it, mod_path), 358 ModuleDef::Variant(it) => from_def_source(db, it, mod_path),
359 ModuleDef::Const(it) => from_def_source(db, it, mod_path), 359 ModuleDef::Const(it) => from_def_source(db, it, mod_path),
360 ModuleDef::Static(it) => from_def_source(db, it, mod_path), 360 ModuleDef::Static(it) => from_def_source(db, it, mod_path),
361 ModuleDef::Trait(it) => from_def_source(db, it, mod_path), 361 ModuleDef::Trait(it) => from_def_source(db, it, mod_path),
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index ff386be80..2f2b99130 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -167,7 +167,7 @@ fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Op
167 hir::ModuleDef::Module(it) => it.attrs(sema.db), 167 hir::ModuleDef::Module(it) => it.attrs(sema.db),
168 hir::ModuleDef::Function(it) => it.attrs(sema.db), 168 hir::ModuleDef::Function(it) => it.attrs(sema.db),
169 hir::ModuleDef::Adt(it) => it.attrs(sema.db), 169 hir::ModuleDef::Adt(it) => it.attrs(sema.db),
170 hir::ModuleDef::EnumVariant(it) => it.attrs(sema.db), 170 hir::ModuleDef::Variant(it) => it.attrs(sema.db),
171 hir::ModuleDef::Const(it) => it.attrs(sema.db), 171 hir::ModuleDef::Const(it) => it.attrs(sema.db),
172 hir::ModuleDef::Static(it) => it.attrs(sema.db), 172 hir::ModuleDef::Static(it) => it.attrs(sema.db),
173 hir::ModuleDef::Trait(it) => it.attrs(sema.db), 173 hir::ModuleDef::Trait(it) => it.attrs(sema.db),
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 67ad7c63d..00c717c7c 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -781,7 +781,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
781 hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Symbol(SymbolKind::Struct), 781 hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Symbol(SymbolKind::Struct),
782 hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Symbol(SymbolKind::Enum), 782 hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Symbol(SymbolKind::Enum),
783 hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Symbol(SymbolKind::Union), 783 hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Symbol(SymbolKind::Union),
784 hir::ModuleDef::EnumVariant(_) => HighlightTag::Symbol(SymbolKind::Variant), 784 hir::ModuleDef::Variant(_) => HighlightTag::Symbol(SymbolKind::Variant),
785 hir::ModuleDef::Const(konst) => { 785 hir::ModuleDef::Const(konst) => {
786 let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Const)); 786 let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Const));
787 if konst.as_assoc_item(db).is_some() { 787 if konst.as_assoc_item(db).is_some() {
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs
index bd2afc887..9d7dce1d4 100644
--- a/crates/ide_db/src/defs.rs
+++ b/crates/ide_db/src/defs.rs
@@ -66,7 +66,7 @@ impl Definition {
66 hir::Adt::Union(it) => it.name(db), 66 hir::Adt::Union(it) => it.name(db),
67 hir::Adt::Enum(it) => it.name(db), 67 hir::Adt::Enum(it) => it.name(db),
68 }, 68 },
69 hir::ModuleDef::EnumVariant(it) => it.name(db), 69 hir::ModuleDef::Variant(it) => it.name(db),
70 hir::ModuleDef::Const(it) => it.name(db)?, 70 hir::ModuleDef::Const(it) => it.name(db)?,
71 hir::ModuleDef::Static(it) => it.name(db)?, 71 hir::ModuleDef::Static(it) => it.name(db)?,
72 hir::ModuleDef::Trait(it) => it.name(db), 72 hir::ModuleDef::Trait(it) => it.name(db),
@@ -207,7 +207,7 @@ impl NameClass {
207 Some(NameClass::Definition(Definition::ModuleDef(def.into()))) 207 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
208 }, 208 },
209 ast::Variant(it) => { 209 ast::Variant(it) => {
210 let def: hir::EnumVariant = sema.to_def(&it)?; 210 let def: hir::Variant = sema.to_def(&it)?;
211 Some(NameClass::Definition(Definition::ModuleDef(def.into()))) 211 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
212 }, 212 },
213 ast::Fn(it) => { 213 ast::Fn(it) => {
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs
index 525c8a41f..ff10f71c3 100644
--- a/crates/ide_db/src/search.rs
+++ b/crates/ide_db/src/search.rs
@@ -141,7 +141,7 @@ impl Definition {
141 hir::GenericDef::Trait(it) => it.source(db).value.syntax().text_range(), 141 hir::GenericDef::Trait(it) => it.source(db).value.syntax().text_range(),
142 hir::GenericDef::TypeAlias(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(), 143 hir::GenericDef::Impl(it) => it.source(db).value.syntax().text_range(),
144 hir::GenericDef::EnumVariant(it) => it.source(db).value.syntax().text_range(), 144 hir::GenericDef::Variant(it) => it.source(db).value.syntax().text_range(),
145 hir::GenericDef::Const(it) => it.source(db).value.syntax().text_range(), 145 hir::GenericDef::Const(it) => it.source(db).value.syntax().text_range(),
146 }; 146 };
147 let mut res = FxHashMap::default(); 147 let mut res = FxHashMap::default();
diff --git a/crates/mbe/src/mbe_expander/transcriber.rs b/crates/mbe/src/mbe_expander/transcriber.rs
index 616119ba9..57592dc92 100644
--- a/crates/mbe/src/mbe_expander/transcriber.rs
+++ b/crates/mbe/src/mbe_expander/transcriber.rs
@@ -97,7 +97,7 @@ fn expand_subtree(
97 err = err.or(e); 97 err = err.or(e);
98 arena.push(tt.into()); 98 arena.push(tt.into());
99 } 99 }
100 Op::Var { name, kind: _ } => { 100 Op::Var { name, .. } => {
101 let ExpandResult { value: fragment, err: e } = expand_var(ctx, name); 101 let ExpandResult { value: fragment, err: e } = expand_var(ctx, name);
102 err = err.or(e); 102 err = err.or(e);
103 push_fragment(arena, fragment); 103 push_fragment(arena, fragment);
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs
index 6b46a1673..c3fdd4040 100644
--- a/crates/mbe/src/parser.rs
+++ b/crates/mbe/src/parser.rs
@@ -101,7 +101,9 @@ fn next_op<'a>(
101 Op::Repeat { subtree, separator, kind } 101 Op::Repeat { subtree, separator, kind }
102 } 102 }
103 tt::TokenTree::Leaf(leaf) => match leaf { 103 tt::TokenTree::Leaf(leaf) => match leaf {
104 tt::Leaf::Punct(..) => return Err(ExpandError::UnexpectedToken), 104 tt::Leaf::Punct(_) => {
105 return Err(ExpandError::UnexpectedToken);
106 }
105 tt::Leaf::Ident(ident) => { 107 tt::Leaf::Ident(ident) => {
106 let name = &ident.text; 108 let name = &ident.text;
107 let kind = eat_fragment_kind(src, mode)?; 109 let kind = eat_fragment_kind(src, mode)?;
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs
index 265c0d63d..2bec7fd49 100644
--- a/crates/mbe/src/syntax_bridge.rs
+++ b/crates/mbe/src/syntax_bridge.rs
@@ -313,7 +313,7 @@ trait TokenConvertor {
313 return; 313 return;
314 } 314 }
315 315
316 result.push(if k.is_punct() { 316 result.push(if k.is_punct() && k != UNDERSCORE {
317 assert_eq!(range.len(), TextSize::of('.')); 317 assert_eq!(range.len(), TextSize::of('.'));
318 let delim = match k { 318 let delim = match k {
319 T!['('] => Some((tt::DelimiterKind::Parenthesis, T![')'])), 319 T!['('] => Some((tt::DelimiterKind::Parenthesis, T![')'])),
@@ -378,6 +378,7 @@ trait TokenConvertor {
378 let leaf: tt::Leaf = match k { 378 let leaf: tt::Leaf = match k {
379 T![true] | T![false] => make_leaf!(Ident), 379 T![true] | T![false] => make_leaf!(Ident),
380 IDENT => make_leaf!(Ident), 380 IDENT => make_leaf!(Ident),
381 UNDERSCORE => make_leaf!(Ident),
381 k if k.is_keyword() => make_leaf!(Ident), 382 k if k.is_keyword() => make_leaf!(Ident),
382 k if k.is_literal() => make_leaf!(Literal), 383 k if k.is_literal() => make_leaf!(Literal),
383 LIFETIME_IDENT => { 384 LIFETIME_IDENT => {
diff --git a/crates/mbe/src/tests.rs b/crates/mbe/src/tests.rs
index dff6e98c2..451fa1456 100644
--- a/crates/mbe/src/tests.rs
+++ b/crates/mbe/src/tests.rs
@@ -992,6 +992,30 @@ fn test_tt_composite2() {
992} 992}
993 993
994#[test] 994#[test]
995fn test_underscore() {
996 parse_macro(
997 r#"
998 macro_rules! foo {
999 ($_:tt) => { 0 }
1000 }
1001 "#,
1002 )
1003 .assert_expand_items(r#"foo! { => }"#, r#"0"#);
1004}
1005
1006#[test]
1007fn test_vertical_bar_with_pat() {
1008 parse_macro(
1009 r#"
1010 macro_rules! foo {
1011 (| $pat:pat | ) => { 0 }
1012 }
1013 "#,
1014 )
1015 .assert_expand_items(r#"foo! { | x | }"#, r#"0"#);
1016}
1017
1018#[test]
995fn test_lifetime() { 1019fn test_lifetime() {
996 parse_macro( 1020 parse_macro(
997 r#" 1021 r#"
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index 1a078f6b4..f08c8bab7 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -55,7 +55,7 @@ pub(crate) mod fragments {
55 use super::*; 55 use super::*;
56 56
57 pub(crate) use super::{ 57 pub(crate) use super::{
58 expressions::block_expr, paths::type_path as path, patterns::pattern, types::type_, 58 expressions::block_expr, paths::type_path as path, patterns::pattern_single, types::type_,
59 }; 59 };
60 60
61 pub(crate) fn expr(p: &mut Parser) { 61 pub(crate) fn expr(p: &mut Parser) {
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs
index ab8e4c70e..811e740f9 100644
--- a/crates/parser/src/lib.rs
+++ b/crates/parser/src/lib.rs
@@ -112,7 +112,7 @@ pub fn parse_fragment(
112 FragmentKind::Path => grammar::fragments::path, 112 FragmentKind::Path => grammar::fragments::path,
113 FragmentKind::Expr => grammar::fragments::expr, 113 FragmentKind::Expr => grammar::fragments::expr,
114 FragmentKind::Type => grammar::fragments::type_, 114 FragmentKind::Type => grammar::fragments::type_,
115 FragmentKind::Pattern => grammar::fragments::pattern, 115 FragmentKind::Pattern => grammar::fragments::pattern_single,
116 FragmentKind::Item => grammar::fragments::item, 116 FragmentKind::Item => grammar::fragments::item,
117 FragmentKind::Block => grammar::fragments::block_expr, 117 FragmentKind::Block => grammar::fragments::block_expr,
118 FragmentKind::Visibility => grammar::fragments::opt_visibility, 118 FragmentKind::Visibility => grammar::fragments::opt_visibility,