diff options
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r-- | crates/hir_def/src/attr.rs | 24 | ||||
-rw-r--r-- | crates/hir_def/src/data.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/generics.rs | 20 | ||||
-rw-r--r-- | crates/hir_def/src/intern.rs | 3 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 38 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 13 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/pretty.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/path.rs | 9 | ||||
-rw-r--r-- | crates/hir_def/src/path/lower.rs | 15 | ||||
-rw-r--r-- | crates/hir_def/src/type_ref.rs | 14 |
12 files changed, 103 insertions, 51 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 89a1ea770..385ba8c80 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -105,7 +105,7 @@ impl RawAttrs { | |||
105 | Either::Left(attr) => Attr::from_src(db, attr, hygiene, id), | 105 | Either::Left(attr) => Attr::from_src(db, attr, hygiene, id), |
106 | Either::Right(comment) => comment.doc_comment().map(|doc| Attr { | 106 | Either::Right(comment) => comment.doc_comment().map(|doc| Attr { |
107 | id, | 107 | id, |
108 | input: Some(AttrInput::Literal(SmolStr::new(doc))), | 108 | input: Some(Interned::new(AttrInput::Literal(SmolStr::new(doc)))), |
109 | path: Interned::new(ModPath::from(hir_expand::name!(doc))), | 109 | path: Interned::new(ModPath::from(hir_expand::name!(doc))), |
110 | }), | 110 | }), |
111 | }) | 111 | }) |
@@ -151,7 +151,7 @@ impl RawAttrs { | |||
151 | return smallvec![attr.clone()]; | 151 | return smallvec![attr.clone()]; |
152 | } | 152 | } |
153 | 153 | ||
154 | let subtree = match &attr.input { | 154 | let subtree = match attr.input.as_deref() { |
155 | Some(AttrInput::TokenTree(it)) => it, | 155 | Some(AttrInput::TokenTree(it)) => it, |
156 | _ => return smallvec![attr.clone()], | 156 | _ => return smallvec![attr.clone()], |
157 | }; | 157 | }; |
@@ -251,7 +251,7 @@ impl Attrs { | |||
251 | } | 251 | } |
252 | 252 | ||
253 | pub fn docs(&self) -> Option<Documentation> { | 253 | pub fn docs(&self) -> Option<Documentation> { |
254 | let docs = self.by_key("doc").attrs().flat_map(|attr| match attr.input.as_ref()? { | 254 | let docs = self.by_key("doc").attrs().flat_map(|attr| match attr.input.as_deref()? { |
255 | AttrInput::Literal(s) => Some(s), | 255 | AttrInput::Literal(s) => Some(s), |
256 | AttrInput::TokenTree(_) => None, | 256 | AttrInput::TokenTree(_) => None, |
257 | }); | 257 | }); |
@@ -454,7 +454,7 @@ impl AttrsWithOwner { | |||
454 | db: &dyn DefDatabase, | 454 | db: &dyn DefDatabase, |
455 | ) -> Option<(Documentation, DocsRangeMap)> { | 455 | ) -> Option<(Documentation, DocsRangeMap)> { |
456 | // FIXME: code duplication in `docs` above | 456 | // FIXME: code duplication in `docs` above |
457 | let docs = self.by_key("doc").attrs().flat_map(|attr| match attr.input.as_ref()? { | 457 | let docs = self.by_key("doc").attrs().flat_map(|attr| match attr.input.as_deref()? { |
458 | AttrInput::Literal(s) => Some((s, attr.id)), | 458 | AttrInput::Literal(s) => Some((s, attr.id)), |
459 | AttrInput::TokenTree(_) => None, | 459 | AttrInput::TokenTree(_) => None, |
460 | }); | 460 | }); |
@@ -637,10 +637,10 @@ pub(crate) struct AttrId { | |||
637 | pub struct Attr { | 637 | pub struct Attr { |
638 | pub(crate) id: AttrId, | 638 | pub(crate) id: AttrId, |
639 | pub(crate) path: Interned<ModPath>, | 639 | pub(crate) path: Interned<ModPath>, |
640 | pub(crate) input: Option<AttrInput>, | 640 | pub(crate) input: Option<Interned<AttrInput>>, |
641 | } | 641 | } |
642 | 642 | ||
643 | #[derive(Debug, Clone, PartialEq, Eq)] | 643 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
644 | pub enum AttrInput { | 644 | pub enum AttrInput { |
645 | /// `#[attr = "string"]` | 645 | /// `#[attr = "string"]` |
646 | Literal(SmolStr), | 646 | Literal(SmolStr), |
@@ -670,9 +670,9 @@ impl Attr { | |||
670 | ast::LiteralKind::String(string) => string.value()?.into(), | 670 | ast::LiteralKind::String(string) => string.value()?.into(), |
671 | _ => lit.syntax().first_token()?.text().trim_matches('"').into(), | 671 | _ => lit.syntax().first_token()?.text().trim_matches('"').into(), |
672 | }; | 672 | }; |
673 | Some(AttrInput::Literal(value)) | 673 | Some(Interned::new(AttrInput::Literal(value))) |
674 | } else if let Some(tt) = ast.token_tree() { | 674 | } else if let Some(tt) = ast.token_tree() { |
675 | Some(AttrInput::TokenTree(ast_to_token_tree(&tt).0)) | 675 | Some(Interned::new(AttrInput::TokenTree(ast_to_token_tree(&tt).0))) |
676 | } else { | 676 | } else { |
677 | None | 677 | None |
678 | }; | 678 | }; |
@@ -688,7 +688,7 @@ impl Attr { | |||
688 | return None; | 688 | return None; |
689 | } | 689 | } |
690 | 690 | ||
691 | match &self.input { | 691 | match self.input.as_deref() { |
692 | Some(AttrInput::TokenTree(args)) => { | 692 | Some(AttrInput::TokenTree(args)) => { |
693 | let mut counter = 0; | 693 | let mut counter = 0; |
694 | let paths = args | 694 | let paths = args |
@@ -720,7 +720,7 @@ impl Attr { | |||
720 | } | 720 | } |
721 | 721 | ||
722 | pub fn string_value(&self) -> Option<&SmolStr> { | 722 | pub fn string_value(&self) -> Option<&SmolStr> { |
723 | match self.input.as_ref()? { | 723 | match self.input.as_deref()? { |
724 | AttrInput::Literal(it) => Some(it), | 724 | AttrInput::Literal(it) => Some(it), |
725 | _ => None, | 725 | _ => None, |
726 | } | 726 | } |
@@ -735,14 +735,14 @@ pub struct AttrQuery<'a> { | |||
735 | 735 | ||
736 | impl<'a> AttrQuery<'a> { | 736 | impl<'a> AttrQuery<'a> { |
737 | pub fn tt_values(self) -> impl Iterator<Item = &'a Subtree> { | 737 | pub fn tt_values(self) -> impl Iterator<Item = &'a Subtree> { |
738 | self.attrs().filter_map(|attr| match attr.input.as_ref()? { | 738 | self.attrs().filter_map(|attr| match attr.input.as_deref()? { |
739 | AttrInput::TokenTree(it) => Some(it), | 739 | AttrInput::TokenTree(it) => Some(it), |
740 | _ => None, | 740 | _ => None, |
741 | }) | 741 | }) |
742 | } | 742 | } |
743 | 743 | ||
744 | pub fn string_value(self) -> Option<&'a SmolStr> { | 744 | pub fn string_value(self) -> Option<&'a SmolStr> { |
745 | self.attrs().find_map(|attr| match attr.input.as_ref()? { | 745 | self.attrs().find_map(|attr| match attr.input.as_deref()? { |
746 | AttrInput::Literal(it) => Some(it), | 746 | AttrInput::Literal(it) => Some(it), |
747 | _ => None, | 747 | _ => None, |
748 | }) | 748 | }) |
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index 135a6698e..8bcac60ef 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs | |||
@@ -112,7 +112,7 @@ pub struct TypeAliasData { | |||
112 | pub visibility: RawVisibility, | 112 | pub visibility: RawVisibility, |
113 | pub is_extern: bool, | 113 | pub is_extern: bool, |
114 | /// Bounds restricting the type alias itself (eg. `type Ty: Bound;` in a trait or impl). | 114 | /// Bounds restricting the type alias itself (eg. `type Ty: Bound;` in a trait or impl). |
115 | pub bounds: Vec<TypeBound>, | 115 | pub bounds: Vec<Interned<TypeBound>>, |
116 | } | 116 | } |
117 | 117 | ||
118 | impl TypeAliasData { | 118 | impl TypeAliasData { |
@@ -141,7 +141,7 @@ pub struct TraitData { | |||
141 | pub is_auto: bool, | 141 | pub is_auto: bool, |
142 | pub is_unsafe: bool, | 142 | pub is_unsafe: bool, |
143 | pub visibility: RawVisibility, | 143 | pub visibility: RawVisibility, |
144 | pub bounds: Box<[TypeBound]>, | 144 | pub bounds: Box<[Interned<TypeBound>]>, |
145 | } | 145 | } |
146 | 146 | ||
147 | impl TraitData { | 147 | impl TraitData { |
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index de5acced8..44d22b918 100644 --- a/crates/hir_def/src/generics.rs +++ b/crates/hir_def/src/generics.rs | |||
@@ -68,9 +68,19 @@ pub struct GenericParams { | |||
68 | /// associated type bindings like `Iterator<Item = u32>`. | 68 | /// associated type bindings like `Iterator<Item = u32>`. |
69 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 69 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
70 | pub enum WherePredicate { | 70 | pub enum WherePredicate { |
71 | TypeBound { target: WherePredicateTypeTarget, bound: TypeBound }, | 71 | TypeBound { |
72 | Lifetime { target: LifetimeRef, bound: LifetimeRef }, | 72 | target: WherePredicateTypeTarget, |
73 | ForLifetime { lifetimes: Box<[Name]>, target: WherePredicateTypeTarget, bound: TypeBound }, | 73 | bound: Interned<TypeBound>, |
74 | }, | ||
75 | Lifetime { | ||
76 | target: LifetimeRef, | ||
77 | bound: LifetimeRef, | ||
78 | }, | ||
79 | ForLifetime { | ||
80 | lifetimes: Box<[Name]>, | ||
81 | target: WherePredicateTypeTarget, | ||
82 | bound: Interned<TypeBound>, | ||
83 | }, | ||
74 | } | 84 | } |
75 | 85 | ||
76 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 86 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
@@ -339,11 +349,11 @@ impl GenericParams { | |||
339 | Some(hrtb_lifetimes) => WherePredicate::ForLifetime { | 349 | Some(hrtb_lifetimes) => WherePredicate::ForLifetime { |
340 | lifetimes: hrtb_lifetimes.clone(), | 350 | lifetimes: hrtb_lifetimes.clone(), |
341 | target: WherePredicateTypeTarget::TypeRef(Interned::new(type_ref)), | 351 | target: WherePredicateTypeTarget::TypeRef(Interned::new(type_ref)), |
342 | bound, | 352 | bound: Interned::new(bound), |
343 | }, | 353 | }, |
344 | None => WherePredicate::TypeBound { | 354 | None => WherePredicate::TypeBound { |
345 | target: WherePredicateTypeTarget::TypeRef(Interned::new(type_ref)), | 355 | target: WherePredicateTypeTarget::TypeRef(Interned::new(type_ref)), |
346 | bound, | 356 | bound: Interned::new(bound), |
347 | }, | 357 | }, |
348 | }, | 358 | }, |
349 | (Either::Right(lifetime), TypeBound::Lifetime(bound)) => { | 359 | (Either::Right(lifetime), TypeBound::Lifetime(bound)) => { |
diff --git a/crates/hir_def/src/intern.rs b/crates/hir_def/src/intern.rs index 5cc7f2df6..79ba970e7 100644 --- a/crates/hir_def/src/intern.rs +++ b/crates/hir_def/src/intern.rs | |||
@@ -216,7 +216,10 @@ pub use crate::_impl_internable as impl_internable; | |||
216 | impl_internable!( | 216 | impl_internable!( |
217 | crate::type_ref::TypeRef, | 217 | crate::type_ref::TypeRef, |
218 | crate::type_ref::TraitRef, | 218 | crate::type_ref::TraitRef, |
219 | crate::type_ref::TypeBound, | ||
219 | crate::path::ModPath, | 220 | crate::path::ModPath, |
221 | crate::path::GenericArgs, | ||
222 | crate::attr::AttrInput, | ||
220 | GenericParams, | 223 | GenericParams, |
221 | str, | 224 | str, |
222 | ); | 225 | ); |
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 528270d49..11767d100 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -1,4 +1,34 @@ | |||
1 | //! A simplified AST that only contains items. | 1 | //! A simplified AST that only contains items. |
2 | //! | ||
3 | //! This is the primary IR used throughout `hir_def`. It is the input to the name resolution | ||
4 | //! algorithm, as well as to the queries defined in `adt.rs`, `data.rs`, and most things in | ||
5 | //! `attr.rs`. | ||
6 | //! | ||
7 | //! `ItemTree`s are built per `HirFileId`, from the syntax tree of the parsed file. This means that | ||
8 | //! they are crate-independent: they don't know which `#[cfg]`s are active or which module they | ||
9 | //! belong to, since those concepts don't exist at this level (a single `ItemTree` might be part of | ||
10 | //! multiple crates, or might be included into the same crate twice via `#[path]`). | ||
11 | //! | ||
12 | //! One important purpose of this layer is to provide an "invalidation barrier" for incremental | ||
13 | //! computations: when typing inside an item body, the `ItemTree` of the modified file is typically | ||
14 | //! unaffected, so we don't have to recompute name resolution results or item data (see `data.rs`). | ||
15 | //! | ||
16 | //! The `ItemTree` for the currently open file can be displayed by using the VS Code command | ||
17 | //! "Rust Analyzer: Debug ItemTree". | ||
18 | //! | ||
19 | //! Compared to rustc's architecture, `ItemTree` has properties from both rustc's AST and HIR: many | ||
20 | //! syntax-level Rust features are already desugared to simpler forms in the `ItemTree`, but name | ||
21 | //! resolution has not yet been performed. `ItemTree`s are per-file, while rustc's AST and HIR are | ||
22 | //! per-crate, because we are interested in incrementally computing it. | ||
23 | //! | ||
24 | //! The representation of items in the `ItemTree` should generally mirror the surface syntax: it is | ||
25 | //! usually a bad idea to desugar a syntax-level construct to something that is structurally | ||
26 | //! different here. Name resolution needs to be able to process attributes and expand macros | ||
27 | //! (including attribute macros), and having a 1-to-1 mapping between syntax and the `ItemTree` | ||
28 | //! avoids introducing subtle bugs. | ||
29 | //! | ||
30 | //! In general, any item in the `ItemTree` stores its `AstId`, which allows mapping it back to its | ||
31 | //! surface syntax. | ||
2 | 32 | ||
3 | mod lower; | 33 | mod lower; |
4 | mod pretty; | 34 | mod pretty; |
@@ -500,8 +530,8 @@ pub struct Import { | |||
500 | pub alias: Option<ImportAlias>, | 530 | pub alias: Option<ImportAlias>, |
501 | pub visibility: RawVisibilityId, | 531 | pub visibility: RawVisibilityId, |
502 | pub is_glob: bool, | 532 | pub is_glob: bool, |
503 | /// AST ID of the `use` or `extern crate` item this import was derived from. Note that many | 533 | /// AST ID of the `use` item this import was derived from. Note that many `Import`s can map to |
504 | /// `Import`s can map to the same `use` item. | 534 | /// the same `use` item. |
505 | pub ast_id: FileAstId<ast::Use>, | 535 | pub ast_id: FileAstId<ast::Use>, |
506 | /// Index of this `Import` when the containing `Use` is visited via `ModPath::expand_use_item`. | 536 | /// Index of this `Import` when the containing `Use` is visited via `ModPath::expand_use_item`. |
507 | /// | 537 | /// |
@@ -614,7 +644,7 @@ pub struct Trait { | |||
614 | pub generic_params: Interned<GenericParams>, | 644 | pub generic_params: Interned<GenericParams>, |
615 | pub is_auto: bool, | 645 | pub is_auto: bool, |
616 | pub is_unsafe: bool, | 646 | pub is_unsafe: bool, |
617 | pub bounds: Box<[TypeBound]>, | 647 | pub bounds: Box<[Interned<TypeBound>]>, |
618 | pub items: Box<[AssocItem]>, | 648 | pub items: Box<[AssocItem]>, |
619 | pub ast_id: FileAstId<ast::Trait>, | 649 | pub ast_id: FileAstId<ast::Trait>, |
620 | } | 650 | } |
@@ -634,7 +664,7 @@ pub struct TypeAlias { | |||
634 | pub name: Name, | 664 | pub name: Name, |
635 | pub visibility: RawVisibilityId, | 665 | pub visibility: RawVisibilityId, |
636 | /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`. | 666 | /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`. |
637 | pub bounds: Box<[TypeBound]>, | 667 | pub bounds: Box<[Interned<TypeBound>]>, |
638 | pub generic_params: Interned<GenericParams>, | 668 | pub generic_params: Interned<GenericParams>, |
639 | pub type_ref: Option<Interned<TypeRef>>, | 669 | pub type_ref: Option<Interned<TypeRef>>, |
640 | pub is_extern: bool, | 670 | pub is_extern: bool, |
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 91cf75371..b4389371f 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -384,7 +384,7 @@ impl<'a> Ctx<'a> { | |||
384 | 384 | ||
385 | let ret_type = if func.async_token().is_some() { | 385 | let ret_type = if func.async_token().is_some() { |
386 | let future_impl = desugar_future_path(ret_type); | 386 | let future_impl = desugar_future_path(ret_type); |
387 | let ty_bound = TypeBound::Path(future_impl); | 387 | let ty_bound = Interned::new(TypeBound::Path(future_impl)); |
388 | TypeRef::ImplTrait(vec![ty_bound]) | 388 | TypeRef::ImplTrait(vec![ty_bound]) |
389 | } else { | 389 | } else { |
390 | ret_type | 390 | ret_type |
@@ -738,11 +738,12 @@ impl<'a> Ctx<'a> { | |||
738 | Interned::new(generics) | 738 | Interned::new(generics) |
739 | } | 739 | } |
740 | 740 | ||
741 | fn lower_type_bounds(&mut self, node: &impl ast::TypeBoundsOwner) -> Vec<TypeBound> { | 741 | fn lower_type_bounds(&mut self, node: &impl ast::TypeBoundsOwner) -> Vec<Interned<TypeBound>> { |
742 | match node.type_bound_list() { | 742 | match node.type_bound_list() { |
743 | Some(bound_list) => { | 743 | Some(bound_list) => bound_list |
744 | bound_list.bounds().map(|it| TypeBound::from_ast(&self.body_ctx, it)).collect() | 744 | .bounds() |
745 | } | 745 | .map(|it| Interned::new(TypeBound::from_ast(&self.body_ctx, it))) |
746 | .collect(), | ||
746 | None => Vec::new(), | 747 | None => Vec::new(), |
747 | } | 748 | } |
748 | } | 749 | } |
@@ -810,7 +811,7 @@ fn desugar_future_path(orig: TypeRef) -> Path { | |||
810 | let binding = | 811 | let binding = |
811 | AssociatedTypeBinding { name: name![Output], type_ref: Some(orig), bounds: Vec::new() }; | 812 | AssociatedTypeBinding { name: name![Output], type_ref: Some(orig), bounds: Vec::new() }; |
812 | last.bindings.push(binding); | 813 | last.bindings.push(binding); |
813 | generic_args.push(Some(Arc::new(last))); | 814 | generic_args.push(Some(Interned::new(last))); |
814 | 815 | ||
815 | Path::from_known_path(path, generic_args) | 816 | Path::from_known_path(path, generic_args) |
816 | } | 817 | } |
diff --git a/crates/hir_def/src/item_tree/pretty.rs b/crates/hir_def/src/item_tree/pretty.rs index 4bc87a0e2..9394a5de6 100644 --- a/crates/hir_def/src/item_tree/pretty.rs +++ b/crates/hir_def/src/item_tree/pretty.rs | |||
@@ -513,13 +513,13 @@ impl<'a> Printer<'a> { | |||
513 | } | 513 | } |
514 | } | 514 | } |
515 | 515 | ||
516 | fn print_type_bounds(&mut self, bounds: &[TypeBound]) { | 516 | fn print_type_bounds(&mut self, bounds: &[Interned<TypeBound>]) { |
517 | for (i, bound) in bounds.iter().enumerate() { | 517 | for (i, bound) in bounds.iter().enumerate() { |
518 | if i != 0 { | 518 | if i != 0 { |
519 | w!(self, " + "); | 519 | w!(self, " + "); |
520 | } | 520 | } |
521 | 521 | ||
522 | match bound { | 522 | match bound.as_ref() { |
523 | TypeBound::Path(path) => self.print_path(path), | 523 | TypeBound::Path(path) => self.print_path(path), |
524 | TypeBound::Lifetime(lt) => w!(self, "{}", lt.name), | 524 | TypeBound::Lifetime(lt) => w!(self, "{}", lt.name), |
525 | TypeBound::Error => w!(self, "{{unknown}}"), | 525 | TypeBound::Error => w!(self, "{{unknown}}"), |
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index a82ea5957..70001cac8 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -485,6 +485,14 @@ impl VariantId { | |||
485 | VariantId::UnionId(it) => it.lookup(db).id.file_id(), | 485 | VariantId::UnionId(it) => it.lookup(db).id.file_id(), |
486 | } | 486 | } |
487 | } | 487 | } |
488 | |||
489 | pub fn adt_id(self) -> AdtId { | ||
490 | match self { | ||
491 | VariantId::EnumVariantId(it) => it.parent.into(), | ||
492 | VariantId::StructId(it) => it.into(), | ||
493 | VariantId::UnionId(it) => it.into(), | ||
494 | } | ||
495 | } | ||
488 | } | 496 | } |
489 | 497 | ||
490 | trait Intern { | 498 | trait Intern { |
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 014ea4de4..2ae740d0e 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -285,7 +285,7 @@ impl DefCollector<'_> { | |||
285 | let registered_name = if *attr_name == hir_expand::name![register_attr] | 285 | let registered_name = if *attr_name == hir_expand::name![register_attr] |
286 | || *attr_name == hir_expand::name![register_tool] | 286 | || *attr_name == hir_expand::name![register_tool] |
287 | { | 287 | { |
288 | match &attr.input { | 288 | match attr.input.as_deref() { |
289 | Some(AttrInput::TokenTree(subtree)) => match &*subtree.token_trees { | 289 | Some(AttrInput::TokenTree(subtree)) => match &*subtree.token_trees { |
290 | [tt::TokenTree::Leaf(tt::Leaf::Ident(name))] => name.as_name(), | 290 | [tt::TokenTree::Leaf(tt::Leaf::Ident(name))] => name.as_name(), |
291 | _ => continue, | 291 | _ => continue, |
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs index 9b8873fd2..45ab9d0ff 100644 --- a/crates/hir_def/src/path.rs +++ b/crates/hir_def/src/path.rs | |||
@@ -4,7 +4,6 @@ mod lower; | |||
4 | use std::{ | 4 | use std::{ |
5 | fmt::{self, Display}, | 5 | fmt::{self, Display}, |
6 | iter, | 6 | iter, |
7 | sync::Arc, | ||
8 | }; | 7 | }; |
9 | 8 | ||
10 | use crate::{body::LowerCtx, db::DefDatabase, intern::Interned, type_ref::LifetimeRef}; | 9 | use crate::{body::LowerCtx, db::DefDatabase, intern::Interned, type_ref::LifetimeRef}; |
@@ -136,7 +135,7 @@ pub struct Path { | |||
136 | type_anchor: Option<Interned<TypeRef>>, | 135 | type_anchor: Option<Interned<TypeRef>>, |
137 | mod_path: Interned<ModPath>, | 136 | mod_path: Interned<ModPath>, |
138 | /// Invariant: the same len as `self.mod_path.segments` | 137 | /// Invariant: the same len as `self.mod_path.segments` |
139 | generic_args: Vec<Option<Arc<GenericArgs>>>, | 138 | generic_args: Vec<Option<Interned<GenericArgs>>>, |
140 | } | 139 | } |
141 | 140 | ||
142 | /// Generic arguments to a path segment (e.g. the `i32` in `Option<i32>`). This | 141 | /// Generic arguments to a path segment (e.g. the `i32` in `Option<i32>`). This |
@@ -165,7 +164,7 @@ pub struct AssociatedTypeBinding { | |||
165 | /// Bounds for the associated type, like in `Iterator<Item: | 164 | /// Bounds for the associated type, like in `Iterator<Item: |
166 | /// SomeOtherTrait>`. (This is the unstable `associated_type_bounds` | 165 | /// SomeOtherTrait>`. (This is the unstable `associated_type_bounds` |
167 | /// feature.) | 166 | /// feature.) |
168 | pub bounds: Vec<TypeBound>, | 167 | pub bounds: Vec<Interned<TypeBound>>, |
169 | } | 168 | } |
170 | 169 | ||
171 | /// A single generic argument. | 170 | /// A single generic argument. |
@@ -185,7 +184,7 @@ impl Path { | |||
185 | /// Converts a known mod path to `Path`. | 184 | /// Converts a known mod path to `Path`. |
186 | pub(crate) fn from_known_path( | 185 | pub(crate) fn from_known_path( |
187 | path: ModPath, | 186 | path: ModPath, |
188 | generic_args: Vec<Option<Arc<GenericArgs>>>, | 187 | generic_args: Vec<Option<Interned<GenericArgs>>>, |
189 | ) -> Path { | 188 | ) -> Path { |
190 | Path { type_anchor: None, mod_path: Interned::new(path), generic_args } | 189 | Path { type_anchor: None, mod_path: Interned::new(path), generic_args } |
191 | } | 190 | } |
@@ -239,7 +238,7 @@ pub struct PathSegment<'a> { | |||
239 | 238 | ||
240 | pub struct PathSegments<'a> { | 239 | pub struct PathSegments<'a> { |
241 | segments: &'a [Name], | 240 | segments: &'a [Name], |
242 | generic_args: &'a [Option<Arc<GenericArgs>>], | 241 | generic_args: &'a [Option<Interned<GenericArgs>>], |
243 | } | 242 | } |
244 | 243 | ||
245 | impl<'a> PathSegments<'a> { | 244 | impl<'a> PathSegments<'a> { |
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index a873325b2..5d5dd9c8f 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs | |||
@@ -3,7 +3,6 @@ | |||
3 | mod lower_use; | 3 | mod lower_use; |
4 | 4 | ||
5 | use crate::intern::Interned; | 5 | use crate::intern::Interned; |
6 | use std::sync::Arc; | ||
7 | 6 | ||
8 | use either::Either; | 7 | use either::Either; |
9 | use hir_expand::name::{name, AsName}; | 8 | use hir_expand::name::{name, AsName}; |
@@ -48,7 +47,7 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option<Path> { | |||
48 | segment.ret_type(), | 47 | segment.ret_type(), |
49 | ) | 48 | ) |
50 | }) | 49 | }) |
51 | .map(Arc::new); | 50 | .map(Interned::new); |
52 | segments.push(name); | 51 | segments.push(name); |
53 | generic_args.push(args) | 52 | generic_args.push(args) |
54 | } | 53 | } |
@@ -87,13 +86,13 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option<Path> { | |||
87 | // Insert the type reference (T in the above example) as Self parameter for the trait | 86 | // Insert the type reference (T in the above example) as Self parameter for the trait |
88 | let last_segment = | 87 | let last_segment = |
89 | generic_args.iter_mut().rev().nth(num_segments.saturating_sub(1))?; | 88 | generic_args.iter_mut().rev().nth(num_segments.saturating_sub(1))?; |
90 | if last_segment.is_none() { | 89 | let mut args_inner = match last_segment { |
91 | *last_segment = Some(Arc::new(GenericArgs::empty())); | 90 | Some(it) => it.as_ref().clone(), |
91 | None => GenericArgs::empty(), | ||
92 | }; | 92 | }; |
93 | let args = last_segment.as_mut().unwrap(); | ||
94 | let mut args_inner = Arc::make_mut(args); | ||
95 | args_inner.has_self_type = true; | 93 | args_inner.has_self_type = true; |
96 | args_inner.args.insert(0, GenericArg::Type(self_type)); | 94 | args_inner.args.insert(0, GenericArg::Type(self_type)); |
95 | *last_segment = Some(Interned::new(args_inner)); | ||
97 | } | 96 | } |
98 | } | 97 | } |
99 | } | 98 | } |
@@ -171,7 +170,9 @@ pub(super) fn lower_generic_args( | |||
171 | let name = name_ref.as_name(); | 170 | let name = name_ref.as_name(); |
172 | let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it)); | 171 | let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it)); |
173 | let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { | 172 | let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { |
174 | l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect() | 173 | l.bounds() |
174 | .map(|it| Interned::new(TypeBound::from_ast(lower_ctx, it))) | ||
175 | .collect() | ||
175 | } else { | 176 | } else { |
176 | Vec::new() | 177 | Vec::new() |
177 | }; | 178 | }; |
diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs index cdcab7110..cbde6b940 100644 --- a/crates/hir_def/src/type_ref.rs +++ b/crates/hir_def/src/type_ref.rs | |||
@@ -5,7 +5,7 @@ use hir_expand::{name::Name, AstId, InFile}; | |||
5 | use std::convert::TryInto; | 5 | use std::convert::TryInto; |
6 | use syntax::ast; | 6 | use syntax::ast; |
7 | 7 | ||
8 | use crate::{body::LowerCtx, path::Path}; | 8 | use crate::{body::LowerCtx, intern::Interned, path::Path}; |
9 | 9 | ||
10 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | 10 | #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] |
11 | pub enum Mutability { | 11 | pub enum Mutability { |
@@ -91,8 +91,8 @@ pub enum TypeRef { | |||
91 | /// A fn pointer. Last element of the vector is the return type. | 91 | /// A fn pointer. Last element of the vector is the return type. |
92 | Fn(Vec<TypeRef>, bool /*varargs*/), | 92 | Fn(Vec<TypeRef>, bool /*varargs*/), |
93 | // For | 93 | // For |
94 | ImplTrait(Vec<TypeBound>), | 94 | ImplTrait(Vec<Interned<TypeBound>>), |
95 | DynTrait(Vec<TypeBound>), | 95 | DynTrait(Vec<Interned<TypeBound>>), |
96 | Macro(AstId<ast::MacroCall>), | 96 | Macro(AstId<ast::MacroCall>), |
97 | Error, | 97 | Error, |
98 | } | 98 | } |
@@ -232,7 +232,7 @@ impl TypeRef { | |||
232 | | TypeRef::Slice(type_ref) => go(&type_ref, f), | 232 | | TypeRef::Slice(type_ref) => go(&type_ref, f), |
233 | TypeRef::ImplTrait(bounds) | TypeRef::DynTrait(bounds) => { | 233 | TypeRef::ImplTrait(bounds) | TypeRef::DynTrait(bounds) => { |
234 | for bound in bounds { | 234 | for bound in bounds { |
235 | match bound { | 235 | match bound.as_ref() { |
236 | TypeBound::Path(path) => go_path(path, f), | 236 | TypeBound::Path(path) => go_path(path, f), |
237 | TypeBound::Lifetime(_) | TypeBound::Error => (), | 237 | TypeBound::Lifetime(_) | TypeBound::Error => (), |
238 | } | 238 | } |
@@ -262,7 +262,7 @@ impl TypeRef { | |||
262 | go(type_ref, f); | 262 | go(type_ref, f); |
263 | } | 263 | } |
264 | for bound in &binding.bounds { | 264 | for bound in &binding.bounds { |
265 | match bound { | 265 | match bound.as_ref() { |
266 | TypeBound::Path(path) => go_path(path, f), | 266 | TypeBound::Path(path) => go_path(path, f), |
267 | TypeBound::Lifetime(_) | TypeBound::Error => (), | 267 | TypeBound::Lifetime(_) | TypeBound::Error => (), |
268 | } | 268 | } |
@@ -277,9 +277,9 @@ impl TypeRef { | |||
277 | pub(crate) fn type_bounds_from_ast( | 277 | pub(crate) fn type_bounds_from_ast( |
278 | lower_ctx: &LowerCtx, | 278 | lower_ctx: &LowerCtx, |
279 | type_bounds_opt: Option<ast::TypeBoundList>, | 279 | type_bounds_opt: Option<ast::TypeBoundList>, |
280 | ) -> Vec<TypeBound> { | 280 | ) -> Vec<Interned<TypeBound>> { |
281 | if let Some(type_bounds) = type_bounds_opt { | 281 | if let Some(type_bounds) = type_bounds_opt { |
282 | type_bounds.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect() | 282 | type_bounds.bounds().map(|it| Interned::new(TypeBound::from_ast(lower_ctx, it))).collect() |
283 | } else { | 283 | } else { |
284 | vec![] | 284 | vec![] |
285 | } | 285 | } |