aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--crates/base_db/src/input.rs2
-rw-r--r--crates/cfg/src/dnf.rs8
-rw-r--r--crates/hir/src/attrs.rs8
-rw-r--r--crates/hir/src/display.rs2
-rw-r--r--crates/hir/src/has_source.rs8
-rw-r--r--crates/hir/src/lib.rs197
-rw-r--r--crates/hir/src/semantics.rs4
-rw-r--r--crates/hir/src/semantics/source_to_def.rs8
-rw-r--r--crates/hir_def/src/attr.rs289
-rw-r--r--crates/hir_def/src/body/scope.rs57
-rw-r--r--crates/hir_def/src/builtin_attr.rs7
-rw-r--r--crates/hir_def/src/db.rs6
-rw-r--r--crates/hir_def/src/import_map.rs18
-rw-r--r--crates/hir_def/src/item_scope.rs2
-rw-r--r--crates/hir_def/src/item_tree.rs4
-rw-r--r--crates/hir_def/src/item_tree/lower.rs8
-rw-r--r--crates/hir_def/src/lib.rs12
-rw-r--r--crates/hir_def/src/nameres.rs16
-rw-r--r--crates/hir_def/src/nameres/collector.rs118
-rw-r--r--crates/hir_def/src/nameres/mod_resolution.rs13
-rw-r--r--crates/hir_def/src/nameres/proc_macro.rs71
-rw-r--r--crates/hir_def/src/nameres/tests/macros.rs47
-rw-r--r--crates/hir_def/src/nameres/tests/mod_resolution.rs19
-rw-r--r--crates/hir_def/src/resolver.rs6
-rw-r--r--crates/hir_expand/src/builtin_derive.rs47
-rw-r--r--crates/hir_expand/src/builtin_macro.rs79
-rw-r--r--crates/hir_expand/src/db.rs16
-rw-r--r--crates/hir_expand/src/eager.rs25
-rw-r--r--crates/hir_expand/src/hygiene.rs12
-rw-r--r--crates/hir_expand/src/lib.rs58
-rw-r--r--crates/hir_expand/src/name.rs5
-rw-r--r--crates/hir_ty/src/autoderef.rs62
-rw-r--r--crates/hir_ty/src/chalk_cast.rs53
-rw-r--r--crates/hir_ty/src/db.rs10
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs15
-rw-r--r--crates/hir_ty/src/display.rs152
-rw-r--r--crates/hir_ty/src/infer.rs29
-rw-r--r--crates/hir_ty/src/infer/coerce.rs13
-rw-r--r--crates/hir_ty/src/infer/expr.rs49
-rw-r--r--crates/hir_ty/src/infer/pat.rs34
-rw-r--r--crates/hir_ty/src/infer/path.rs20
-rw-r--r--crates/hir_ty/src/infer/unify.rs119
-rw-r--r--crates/hir_ty/src/lib.rs217
-rw-r--r--crates/hir_ty/src/lower.rs111
-rw-r--r--crates/hir_ty/src/method_resolution.rs62
-rw-r--r--crates/hir_ty/src/tests.rs69
-rw-r--r--crates/hir_ty/src/tests/macros.rs45
-rw-r--r--crates/hir_ty/src/tests/patterns.rs22
-rw-r--r--crates/hir_ty/src/tests/traits.rs54
-rw-r--r--crates/hir_ty/src/traits.rs75
-rw-r--r--crates/hir_ty/src/traits/chalk.rs48
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs238
-rw-r--r--crates/hir_ty/src/utils.rs16
-rw-r--r--crates/ide/src/display/navigation_target.rs8
-rw-r--r--crates/ide/src/extend_selection.rs7
-rw-r--r--crates/ide/src/goto_definition.rs17
-rw-r--r--crates/ide/src/hover.rs14
-rw-r--r--crates/ide/src/syntax_highlighting.rs16
-rw-r--r--crates/ide/src/syntax_highlighting/html.rs2
-rw-r--r--crates/ide/src/syntax_highlighting/inject.rs132
-rw-r--r--crates/ide/src/syntax_highlighting/tags.rs14
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html2
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html6
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html2
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_injection.html2
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_strings.html2
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html2
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlighting.html2
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/injection.html2
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html2
-rw-r--r--crates/ide_assists/src/handlers/add_lifetime_to_type.rs5
-rw-r--r--crates/ide_assists/src/handlers/add_turbo_fish.rs2
-rw-r--r--crates/ide_assists/src/handlers/convert_comment_block.rs5
-rw-r--r--crates/ide_assists/src/handlers/expand_glob_import.rs19
-rw-r--r--crates/ide_assists/src/handlers/move_bounds.rs6
-rw-r--r--crates/ide_assists/src/handlers/qualify_path.rs74
-rw-r--r--crates/ide_assists/src/handlers/reorder_impl.rs2
-rw-r--r--crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs34
-rw-r--r--crates/ide_completion/src/completions.rs29
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs93
-rw-r--r--crates/ide_completion/src/completions/lifetime.rs316
-rw-r--r--crates/ide_completion/src/completions/pattern.rs2
-rw-r--r--crates/ide_completion/src/context.rs90
-rw-r--r--crates/ide_completion/src/lib.rs29
-rw-r--r--crates/ide_completion/src/patterns.rs2
-rw-r--r--crates/ide_completion/src/render.rs6
-rw-r--r--crates/ide_completion/src/render/macro_.rs2
-rw-r--r--crates/ide_db/src/call_info.rs14
-rw-r--r--crates/ide_db/src/helpers/import_assets.rs208
-rw-r--r--crates/ide_db/src/helpers/insert_use.rs4
-rw-r--r--crates/ide_db/src/items_locator.rs178
-rw-r--r--crates/ide_db/src/symbol_index.rs16
-rw-r--r--crates/ide_ssr/src/parsing.rs2
-rw-r--r--crates/mbe/src/expander/matcher.rs13
-rw-r--r--crates/mbe/src/lib.rs2
-rw-r--r--crates/mbe/src/parser.rs14
-rw-r--r--crates/mbe/src/subtree_source.rs1
-rw-r--r--crates/mbe/src/syntax_bridge.rs9
-rw-r--r--crates/mbe/src/tests.rs1994
-rw-r--r--crates/mbe/src/tests/expand.rs1877
-rw-r--r--crates/mbe/src/tests/rule.rs49
-rw-r--r--crates/mbe/src/tt_iter.rs7
-rw-r--r--crates/parser/src/grammar/attributes.rs4
-rw-r--r--crates/proc_macro_srv/src/rustc_server.rs9
-rw-r--r--crates/project_model/src/build_data.rs91
-rw-r--r--crates/rust-analyzer/src/caps.rs2
-rw-r--r--crates/rust-analyzer/src/config.rs3
-rw-r--r--crates/rust-analyzer/src/handlers.rs7
-rw-r--r--crates/rust-analyzer/src/main_loop.rs7
-rw-r--r--crates/rust-analyzer/src/reload.rs2
-rw-r--r--crates/rust-analyzer/src/semantic_tokens.rs2
-rw-r--r--crates/rust-analyzer/src/to_proto.rs8
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/main.rs8
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/support.rs2
-rw-r--r--crates/syntax/src/algo.rs4
-rw-r--r--crates/syntax/src/ast.rs4
-rw-r--r--crates/syntax/src/ast/edit.rs8
-rw-r--r--crates/syntax/src/ast/edit_in_place.rs41
-rw-r--r--crates/syntax/src/ast/expr_ext.rs44
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs46
-rw-r--r--crates/syntax/src/ast/make.rs2
-rw-r--r--crates/syntax/src/ast/node_ext.rs68
-rw-r--r--crates/syntax/src/ast/token_ext.rs5
-rw-r--r--crates/syntax/src/fuzz.rs2
-rw-r--r--crates/syntax/src/ted.rs65
-rw-r--r--crates/syntax/src/validation.rs4
-rw-r--r--crates/tt/src/lib.rs3
-rw-r--r--docs/dev/README.md3
-rw-r--r--docs/user/manual.adoc20
-rw-r--r--xtask/Cargo.toml2
-rw-r--r--xtask/src/codegen/gen_assists_docs.rs4
-rw-r--r--xtask/src/codegen/gen_parser_tests.rs10
-rw-r--r--xtask/src/codegen/gen_syntax.rs2
-rw-r--r--xtask/src/main.rs2
-rw-r--r--xtask/src/metrics.rs2
-rw-r--r--xtask/src/tidy.rs2
137 files changed, 4983 insertions, 3530 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b99c243a4..9f013c275 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1809,9 +1809,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
1809 1809
1810[[package]] 1810[[package]]
1811name = "ungrammar" 1811name = "ungrammar"
1812version = "1.12.2" 1812version = "1.13.0"
1813source = "registry+https://github.com/rust-lang/crates.io-index" 1813source = "registry+https://github.com/rust-lang/crates.io-index"
1814checksum = "df6586a7c530704efe803d49a0b4132dcbdb4063163df39110548e6b5f2373ba" 1814checksum = "76760314176cc2b94047af2f921b92c39f11a34dc05c43a3c2b0fc91cb22959f"
1815 1815
1816[[package]] 1816[[package]]
1817name = "unicase" 1817name = "unicase"
diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs
index d0def2181..e9e8dfc2e 100644
--- a/crates/base_db/src/input.rs
+++ b/crates/base_db/src/input.rs
@@ -410,7 +410,7 @@ impl CrateId {
410 410
411impl CrateData { 411impl CrateData {
412 fn add_dep(&mut self, name: CrateName, crate_id: CrateId) { 412 fn add_dep(&mut self, name: CrateName, crate_id: CrateId) {
413 self.dependencies.push(Dependency { name, crate_id }) 413 self.dependencies.push(Dependency { crate_id, name })
414 } 414 }
415} 415}
416 416
diff --git a/crates/cfg/src/dnf.rs b/crates/cfg/src/dnf.rs
index 30f4bcdf7..75ded9aa1 100644
--- a/crates/cfg/src/dnf.rs
+++ b/crates/cfg/src/dnf.rs
@@ -255,9 +255,9 @@ impl Builder {
255fn make_dnf(expr: CfgExpr) -> CfgExpr { 255fn make_dnf(expr: CfgExpr) -> CfgExpr {
256 match expr { 256 match expr {
257 CfgExpr::Invalid | CfgExpr::Atom(_) | CfgExpr::Not(_) => expr, 257 CfgExpr::Invalid | CfgExpr::Atom(_) | CfgExpr::Not(_) => expr,
258 CfgExpr::Any(e) => CfgExpr::Any(e.into_iter().map(|expr| make_dnf(expr)).collect()), 258 CfgExpr::Any(e) => CfgExpr::Any(e.into_iter().map(make_dnf).collect()),
259 CfgExpr::All(e) => { 259 CfgExpr::All(e) => {
260 let e = e.into_iter().map(|expr| make_nnf(expr)).collect::<Vec<_>>(); 260 let e = e.into_iter().map(make_nnf).collect::<Vec<_>>();
261 261
262 CfgExpr::Any(distribute_conj(&e)) 262 CfgExpr::Any(distribute_conj(&e))
263 } 263 }
@@ -300,8 +300,8 @@ fn distribute_conj(conj: &[CfgExpr]) -> Vec<CfgExpr> {
300fn make_nnf(expr: CfgExpr) -> CfgExpr { 300fn make_nnf(expr: CfgExpr) -> CfgExpr {
301 match expr { 301 match expr {
302 CfgExpr::Invalid | CfgExpr::Atom(_) => expr, 302 CfgExpr::Invalid | CfgExpr::Atom(_) => expr,
303 CfgExpr::Any(expr) => CfgExpr::Any(expr.into_iter().map(|expr| make_nnf(expr)).collect()), 303 CfgExpr::Any(expr) => CfgExpr::Any(expr.into_iter().map(make_nnf).collect()),
304 CfgExpr::All(expr) => CfgExpr::All(expr.into_iter().map(|expr| make_nnf(expr)).collect()), 304 CfgExpr::All(expr) => CfgExpr::All(expr.into_iter().map(make_nnf).collect()),
305 CfgExpr::Not(operand) => match *operand { 305 CfgExpr::Not(operand) => match *operand {
306 CfgExpr::Invalid | CfgExpr::Atom(_) => CfgExpr::Not(operand.clone()), // Original negated expr 306 CfgExpr::Invalid | CfgExpr::Atom(_) => CfgExpr::Not(operand.clone()), // Original negated expr
307 CfgExpr::Not(expr) => { 307 CfgExpr::Not(expr) => {
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
index dab8da7bb..4a11622fc 100644
--- a/crates/hir/src/attrs.rs
+++ b/crates/hir/src/attrs.rs
@@ -1,6 +1,6 @@
1//! Attributes & documentation for hir types. 1//! Attributes & documentation for hir types.
2use hir_def::{ 2use hir_def::{
3 attr::{Attrs, Documentation}, 3 attr::{AttrsWithOwner, Documentation},
4 path::ModPath, 4 path::ModPath,
5 per_ns::PerNs, 5 per_ns::PerNs,
6 resolver::HasResolver, 6 resolver::HasResolver,
@@ -16,7 +16,7 @@ use crate::{
16}; 16};
17 17
18pub trait HasAttrs { 18pub trait HasAttrs {
19 fn attrs(self, db: &dyn HirDatabase) -> Attrs; 19 fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner;
20 fn docs(self, db: &dyn HirDatabase) -> Option<Documentation>; 20 fn docs(self, db: &dyn HirDatabase) -> Option<Documentation>;
21 fn resolve_doc_path( 21 fn resolve_doc_path(
22 self, 22 self,
@@ -36,7 +36,7 @@ pub enum Namespace {
36macro_rules! impl_has_attrs { 36macro_rules! impl_has_attrs {
37 ($(($def:ident, $def_id:ident),)*) => {$( 37 ($(($def:ident, $def_id:ident),)*) => {$(
38 impl HasAttrs for $def { 38 impl HasAttrs for $def {
39 fn attrs(self, db: &dyn HirDatabase) -> Attrs { 39 fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner {
40 let def = AttrDefId::$def_id(self.into()); 40 let def = AttrDefId::$def_id(self.into());
41 db.attrs(def) 41 db.attrs(def)
42 } 42 }
@@ -70,7 +70,7 @@ impl_has_attrs![
70macro_rules! impl_has_attrs_enum { 70macro_rules! impl_has_attrs_enum {
71 ($($variant:ident),* for $enum:ident) => {$( 71 ($($variant:ident),* for $enum:ident) => {$(
72 impl HasAttrs for $variant { 72 impl HasAttrs for $variant {
73 fn attrs(self, db: &dyn HirDatabase) -> Attrs { 73 fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner {
74 $enum::$variant(self).attrs(db) 74 $enum::$variant(self).attrs(db)
75 } 75 }
76 fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> { 76 fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index 9f6d7be48..97a78ca25 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -217,7 +217,7 @@ impl HirDisplay for Variant {
217 217
218impl HirDisplay for Type { 218impl HirDisplay for Type {
219 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 219 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
220 self.ty.value.hir_fmt(f) 220 self.ty.hir_fmt(f)
221 } 221 }
222} 222}
223 223
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs
index 262002671..dc10a4d0f 100644
--- a/crates/hir/src/has_source.rs
+++ b/crates/hir/src/has_source.rs
@@ -111,10 +111,12 @@ impl HasSource for TypeAlias {
111 } 111 }
112} 112}
113impl HasSource for MacroDef { 113impl HasSource for MacroDef {
114 type Ast = ast::Macro; 114 type Ast = Either<ast::Macro, ast::Fn>;
115 fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { 115 fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
116 let ast_id = self.id.ast_id?; 116 Some(self.id.ast_id().either(
117 Some(InFile { file_id: ast_id.file_id, value: ast_id.to_node(db.upcast()) }) 117 |id| id.with_value(Either::Left(id.to_node(db.upcast()))),
118 |id| id.with_value(Either::Right(id.to_node(db.upcast()))),
119 ))
118 } 120 }
119} 121}
120impl HasSource for Impl { 122impl HasSource for Impl {
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index b41a36a78..30b96d7e2 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -56,9 +56,9 @@ use hir_ty::{
56 primitive::UintTy, 56 primitive::UintTy,
57 to_assoc_type_id, 57 to_assoc_type_id,
58 traits::{FnTrait, Solution, SolutionVariables}, 58 traits::{FnTrait, Solution, SolutionVariables},
59 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, 59 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast,
60 InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substitution, 60 DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar,
61 Ty, TyDefId, TyKind, TyVariableKind, 61 Substitution, TraitEnvironment, Ty, TyDefId, TyKind, TyVariableKind, WhereClause,
62}; 62};
63use itertools::Itertools; 63use itertools::Itertools;
64use rustc_hash::FxHashSet; 64use rustc_hash::FxHashSet;
@@ -89,7 +89,7 @@ pub use crate::{
89pub use { 89pub use {
90 hir_def::{ 90 hir_def::{
91 adt::StructKind, 91 adt::StructKind,
92 attr::{Attr, Attrs, Documentation}, 92 attr::{Attr, Attrs, AttrsWithOwner, Documentation},
93 body::scope::ExprScopes, 93 body::scope::ExprScopes,
94 find_path::PrefixKind, 94 find_path::PrefixKind,
95 import_map, 95 import_map,
@@ -213,7 +213,7 @@ impl Crate {
213 Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text), 213 Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text),
214 _ => None 214 _ => None
215 } 215 }
216 }).flat_map(|t| t).next(); 216 }).flatten().next();
217 217
218 doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/") 218 doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/")
219 } 219 }
@@ -851,13 +851,7 @@ impl Function {
851 .iter() 851 .iter()
852 .enumerate() 852 .enumerate()
853 .map(|(idx, type_ref)| { 853 .map(|(idx, type_ref)| {
854 let ty = Type { 854 let ty = Type { krate, env: environment.clone(), ty: ctx.lower_ty(type_ref) };
855 krate,
856 ty: InEnvironment {
857 value: ctx.lower_ty(type_ref),
858 environment: environment.clone(),
859 },
860 };
861 Param { func: self, ty, idx } 855 Param { func: self, ty, idx }
862 }) 856 })
863 .collect() 857 .collect()
@@ -1144,17 +1138,21 @@ impl MacroDef {
1144 1138
1145 /// XXX: this parses the file 1139 /// XXX: this parses the file
1146 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 1140 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
1147 self.source(db)?.value.name().map(|it| it.as_name()) 1141 match self.source(db)?.value {
1142 Either::Left(it) => it.name().map(|it| it.as_name()),
1143 Either::Right(it) => it.name().map(|it| it.as_name()),
1144 }
1148 } 1145 }
1149 1146
1150 /// Indicate it is a proc-macro 1147 /// Indicate it is a proc-macro
1151 pub fn is_proc_macro(&self) -> bool { 1148 pub fn is_proc_macro(&self) -> bool {
1152 matches!(self.id.kind, MacroDefKind::ProcMacro(_)) 1149 matches!(self.id.kind, MacroDefKind::ProcMacro(..))
1153 } 1150 }
1154 1151
1155 /// Indicate it is a derive macro 1152 /// Indicate it is a derive macro
1156 pub fn is_derive_macro(&self) -> bool { 1153 pub fn is_derive_macro(&self) -> bool {
1157 matches!(self.id.kind, MacroDefKind::ProcMacro(_) | MacroDefKind::BuiltInDerive(_)) 1154 // FIXME: wrong for `ProcMacro`
1155 matches!(self.id.kind, MacroDefKind::ProcMacro(..) | MacroDefKind::BuiltInDerive(..))
1158 } 1156 }
1159} 1157}
1160 1158
@@ -1456,9 +1454,9 @@ impl TypeParam {
1456 pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> { 1454 pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
1457 db.generic_predicates_for_param(self.id) 1455 db.generic_predicates_for_param(self.id)
1458 .into_iter() 1456 .into_iter()
1459 .filter_map(|pred| match &pred.value { 1457 .filter_map(|pred| match &pred.skip_binders().skip_binders() {
1460 hir_ty::GenericPredicate::Implemented(trait_ref) => { 1458 hir_ty::WhereClause::Implemented(trait_ref) => {
1461 Some(Trait::from(trait_ref.trait_)) 1459 Some(Trait::from(trait_ref.hir_trait_id()))
1462 } 1460 }
1463 _ => None, 1461 _ => None,
1464 }) 1462 })
@@ -1536,8 +1534,8 @@ impl Impl {
1536 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() 1534 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
1537 } 1535 }
1538 1536
1539 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> { 1537 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> {
1540 let def_crates = match ty.value.def_crates(db, krate) { 1538 let def_crates = match ty.def_crates(db, krate) {
1541 Some(def_crates) => def_crates, 1539 Some(def_crates) => def_crates,
1542 None => return Vec::new(), 1540 None => return Vec::new(),
1543 }; 1541 };
@@ -1545,14 +1543,14 @@ impl Impl {
1545 let filter = |impl_def: &Impl| { 1543 let filter = |impl_def: &Impl| {
1546 let target_ty = impl_def.target_ty(db); 1544 let target_ty = impl_def.target_ty(db);
1547 let rref = target_ty.remove_ref(); 1545 let rref = target_ty.remove_ref();
1548 ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value)) 1546 ty.equals_ctor(rref.as_ref().map_or(&target_ty.ty, |it| &it.ty))
1549 }; 1547 };
1550 1548
1551 let mut all = Vec::new(); 1549 let mut all = Vec::new();
1552 def_crates.iter().for_each(|&id| { 1550 def_crates.iter().for_each(|&id| {
1553 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) 1551 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter))
1554 }); 1552 });
1555 let fp = TyFingerprint::for_impl(&ty.value); 1553 let fp = TyFingerprint::for_impl(&ty);
1556 for id in def_crates 1554 for id in def_crates
1557 .iter() 1555 .iter()
1558 .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db)) 1556 .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db))
@@ -1639,7 +1637,8 @@ impl Impl {
1639#[derive(Clone, PartialEq, Eq, Debug)] 1637#[derive(Clone, PartialEq, Eq, Debug)]
1640pub struct Type { 1638pub struct Type {
1641 krate: CrateId, 1639 krate: CrateId,
1642 ty: InEnvironment<Ty>, 1640 env: Arc<TraitEnvironment>,
1641 ty: Ty,
1643} 1642}
1644 1643
1645impl Type { 1644impl Type {
@@ -1659,14 +1658,14 @@ impl Type {
1659 ) -> Type { 1658 ) -> Type {
1660 let environment = 1659 let environment =
1661 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); 1660 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
1662 Type { krate, ty: InEnvironment { value: ty, environment } } 1661 Type { krate, env: environment, ty }
1663 } 1662 }
1664 1663
1665 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { 1664 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
1666 let resolver = lexical_env.resolver(db.upcast()); 1665 let resolver = lexical_env.resolver(db.upcast());
1667 let environment = 1666 let environment =
1668 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); 1667 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
1669 Type { krate, ty: InEnvironment { value: ty, environment } } 1668 Type { krate, env: environment, ty }
1670 } 1669 }
1671 1670
1672 fn from_def( 1671 fn from_def(
@@ -1680,29 +1679,29 @@ impl Type {
1680 } 1679 }
1681 1680
1682 pub fn is_unit(&self) -> bool { 1681 pub fn is_unit(&self) -> bool {
1683 matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..)) 1682 matches!(self.ty.interned(&Interner), TyKind::Tuple(0, ..))
1684 } 1683 }
1685 pub fn is_bool(&self) -> bool { 1684 pub fn is_bool(&self) -> bool {
1686 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool)) 1685 matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Bool))
1687 } 1686 }
1688 1687
1689 pub fn is_mutable_reference(&self) -> bool { 1688 pub fn is_mutable_reference(&self) -> bool {
1690 matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) 1689 matches!(self.ty.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
1691 } 1690 }
1692 1691
1693 pub fn is_usize(&self) -> bool { 1692 pub fn is_usize(&self) -> bool {
1694 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) 1693 matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
1695 } 1694 }
1696 1695
1697 pub fn remove_ref(&self) -> Option<Type> { 1696 pub fn remove_ref(&self) -> Option<Type> {
1698 match &self.ty.value.interned(&Interner) { 1697 match &self.ty.interned(&Interner) {
1699 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), 1698 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
1700 _ => None, 1699 _ => None,
1701 } 1700 }
1702 } 1701 }
1703 1702
1704 pub fn is_unknown(&self) -> bool { 1703 pub fn is_unknown(&self) -> bool {
1705 self.ty.value.is_unknown() 1704 self.ty.is_unknown()
1706 } 1705 }
1707 1706
1708 /// Checks that particular type `ty` implements `std::future::Future`. 1707 /// Checks that particular type `ty` implements `std::future::Future`.
@@ -1719,11 +1718,12 @@ impl Type {
1719 None => return false, 1718 None => return false,
1720 }; 1719 };
1721 1720
1722 let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1721 let canonical_ty =
1722 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1723 method_resolution::implements_trait( 1723 method_resolution::implements_trait(
1724 &canonical_ty, 1724 &canonical_ty,
1725 db, 1725 db,
1726 self.ty.environment.clone(), 1726 self.env.clone(),
1727 krate, 1727 krate,
1728 std_future_trait, 1728 std_future_trait,
1729 ) 1729 )
@@ -1741,11 +1741,12 @@ impl Type {
1741 None => return false, 1741 None => return false,
1742 }; 1742 };
1743 1743
1744 let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1744 let canonical_ty =
1745 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1745 method_resolution::implements_trait_unique( 1746 method_resolution::implements_trait_unique(
1746 &canonical_ty, 1747 &canonical_ty,
1747 db, 1748 db,
1748 self.ty.environment.clone(), 1749 self.env.clone(),
1749 krate, 1750 krate,
1750 fnonce_trait, 1751 fnonce_trait,
1751 ) 1752 )
@@ -1753,19 +1754,16 @@ impl Type {
1753 1754
1754 pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { 1755 pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool {
1755 let trait_ref = hir_ty::TraitRef { 1756 let trait_ref = hir_ty::TraitRef {
1756 trait_: trait_.id, 1757 trait_id: hir_ty::to_chalk_trait_id(trait_.id),
1757 substs: Substitution::build_for_def(db, trait_.id) 1758 substitution: Substitution::build_for_def(db, trait_.id)
1758 .push(self.ty.value.clone()) 1759 .push(self.ty.clone())
1759 .fill(args.iter().map(|t| t.ty.value.clone())) 1760 .fill(args.iter().map(|t| t.ty.clone()))
1760 .build(), 1761 .build(),
1761 }; 1762 };
1762 1763
1763 let goal = Canonical { 1764 let goal = Canonical {
1764 value: hir_ty::InEnvironment::new( 1765 value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)),
1765 self.ty.environment.clone(), 1766 binders: CanonicalVarKinds::empty(&Interner),
1766 hir_ty::Obligation::Trait(trait_ref),
1767 ),
1768 kinds: Arc::new([]),
1769 }; 1767 };
1770 1768
1771 db.trait_solve(self.krate, goal).is_some() 1769 db.trait_solve(self.krate, goal).is_some()
@@ -1779,23 +1777,24 @@ impl Type {
1779 alias: TypeAlias, 1777 alias: TypeAlias,
1780 ) -> Option<Type> { 1778 ) -> Option<Type> {
1781 let subst = Substitution::build_for_def(db, trait_.id) 1779 let subst = Substitution::build_for_def(db, trait_.id)
1782 .push(self.ty.value.clone()) 1780 .push(self.ty.clone())
1783 .fill(args.iter().map(|t| t.ty.value.clone())) 1781 .fill(args.iter().map(|t| t.ty.clone()))
1784 .build(); 1782 .build();
1785 let predicate = ProjectionPredicate { 1783 let goal = Canonical::new(
1786 projection_ty: ProjectionTy { 1784 InEnvironment::new(
1787 associated_ty_id: to_assoc_type_id(alias.id), 1785 self.env.env.clone(),
1788 substitution: subst, 1786 AliasEq {
1789 }, 1787 alias: AliasTy::Projection(ProjectionTy {
1790 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner), 1788 associated_ty_id: to_assoc_type_id(alias.id),
1791 }; 1789 substitution: subst,
1792 let goal = Canonical { 1790 }),
1793 value: InEnvironment::new( 1791 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
1794 self.ty.environment.clone(), 1792 .intern(&Interner),
1795 Obligation::Projection(predicate), 1793 }
1794 .cast(&Interner),
1796 ), 1795 ),
1797 kinds: Arc::new([TyVariableKind::General]), 1796 [TyVariableKind::General].iter().copied(),
1798 }; 1797 );
1799 1798
1800 match db.trait_solve(self.krate, goal)? { 1799 match db.trait_solve(self.krate, goal)? {
1801 Solution::Unique(SolutionVariables(subst)) => { 1800 Solution::Unique(SolutionVariables(subst)) => {
@@ -1815,22 +1814,22 @@ impl Type {
1815 } 1814 }
1816 1815
1817 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { 1816 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1818 let def = self.ty.value.callable_def(db); 1817 let def = self.ty.callable_def(db);
1819 1818
1820 let sig = self.ty.value.callable_sig(db)?; 1819 let sig = self.ty.callable_sig(db)?;
1821 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) 1820 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false })
1822 } 1821 }
1823 1822
1824 pub fn is_closure(&self) -> bool { 1823 pub fn is_closure(&self) -> bool {
1825 matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. }) 1824 matches!(&self.ty.interned(&Interner), TyKind::Closure { .. })
1826 } 1825 }
1827 1826
1828 pub fn is_fn(&self) -> bool { 1827 pub fn is_fn(&self) -> bool {
1829 matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) 1828 matches!(&self.ty.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. })
1830 } 1829 }
1831 1830
1832 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { 1831 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
1833 let adt_id = match self.ty.value.interned(&Interner) { 1832 let adt_id = match self.ty.interned(&Interner) {
1834 &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, 1833 &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
1835 _ => return false, 1834 _ => return false,
1836 }; 1835 };
@@ -1843,11 +1842,11 @@ impl Type {
1843 } 1842 }
1844 1843
1845 pub fn is_raw_ptr(&self) -> bool { 1844 pub fn is_raw_ptr(&self) -> bool {
1846 matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..)) 1845 matches!(&self.ty.interned(&Interner), TyKind::Raw(..))
1847 } 1846 }
1848 1847
1849 pub fn contains_unknown(&self) -> bool { 1848 pub fn contains_unknown(&self) -> bool {
1850 return go(&self.ty.value); 1849 return go(&self.ty);
1851 1850
1852 fn go(ty: &Ty) -> bool { 1851 fn go(ty: &Ty) -> bool {
1853 match ty.interned(&Interner) { 1852 match ty.interned(&Interner) {
@@ -1879,7 +1878,7 @@ impl Type {
1879 } 1878 }
1880 1879
1881 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1880 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1882 let (variant_id, substs) = match self.ty.value.interned(&Interner) { 1881 let (variant_id, substs) = match self.ty.interned(&Interner) {
1883 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), 1882 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),
1884 &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), 1883 &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs),
1885 _ => return Vec::new(), 1884 _ => return Vec::new(),
@@ -1896,7 +1895,7 @@ impl Type {
1896 } 1895 }
1897 1896
1898 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { 1897 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
1899 if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) { 1898 if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) {
1900 substs.iter().map(|ty| self.derived(ty.clone())).collect() 1899 substs.iter().map(|ty| self.derived(ty.clone())).collect()
1901 } else { 1900 } else {
1902 Vec::new() 1901 Vec::new()
@@ -1906,9 +1905,10 @@ impl Type {
1906 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { 1905 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a {
1907 // There should be no inference vars in types passed here 1906 // There should be no inference vars in types passed here
1908 // FIXME check that? 1907 // FIXME check that?
1909 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1908 let canonical =
1910 let environment = self.ty.environment.clone(); 1909 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1911 let ty = InEnvironment { value: canonical, environment }; 1910 let environment = self.env.env.clone();
1911 let ty = InEnvironment { goal: canonical, environment };
1912 autoderef(db, Some(self.krate), ty) 1912 autoderef(db, Some(self.krate), ty)
1913 .map(|canonical| canonical.value) 1913 .map(|canonical| canonical.value)
1914 .map(move |ty| self.derived(ty)) 1914 .map(move |ty| self.derived(ty))
@@ -1922,10 +1922,10 @@ impl Type {
1922 krate: Crate, 1922 krate: Crate,
1923 mut callback: impl FnMut(AssocItem) -> Option<T>, 1923 mut callback: impl FnMut(AssocItem) -> Option<T>,
1924 ) -> Option<T> { 1924 ) -> Option<T> {
1925 for krate in self.ty.value.def_crates(db, krate.id)? { 1925 for krate in self.ty.def_crates(db, krate.id)? {
1926 let impls = db.inherent_impls_in_crate(krate); 1926 let impls = db.inherent_impls_in_crate(krate);
1927 1927
1928 for impl_def in impls.for_self_ty(&self.ty.value) { 1928 for impl_def in impls.for_self_ty(&self.ty) {
1929 for &item in db.impl_data(*impl_def).items.iter() { 1929 for &item in db.impl_data(*impl_def).items.iter() {
1930 if let Some(result) = callback(item.into()) { 1930 if let Some(result) = callback(item.into()) {
1931 return Some(result); 1931 return Some(result);
@@ -1938,7 +1938,6 @@ impl Type {
1938 1938
1939 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { 1939 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ {
1940 self.ty 1940 self.ty
1941 .value
1942 .strip_references() 1941 .strip_references()
1943 .substs() 1942 .substs()
1944 .into_iter() 1943 .into_iter()
@@ -1957,9 +1956,10 @@ impl Type {
1957 // There should be no inference vars in types passed here 1956 // There should be no inference vars in types passed here
1958 // FIXME check that? 1957 // FIXME check that?
1959 // FIXME replace Unknown by bound vars here 1958 // FIXME replace Unknown by bound vars here
1960 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1959 let canonical =
1960 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1961 1961
1962 let env = self.ty.environment.clone(); 1962 let env = self.env.clone();
1963 let krate = krate.id; 1963 let krate = krate.id;
1964 1964
1965 method_resolution::iterate_method_candidates( 1965 method_resolution::iterate_method_candidates(
@@ -1988,9 +1988,10 @@ impl Type {
1988 // There should be no inference vars in types passed here 1988 // There should be no inference vars in types passed here
1989 // FIXME check that? 1989 // FIXME check that?
1990 // FIXME replace Unknown by bound vars here 1990 // FIXME replace Unknown by bound vars here
1991 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; 1991 let canonical =
1992 Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
1992 1993
1993 let env = self.ty.environment.clone(); 1994 let env = self.env.clone();
1994 let krate = krate.id; 1995 let krate = krate.id;
1995 1996
1996 method_resolution::iterate_method_candidates( 1997 method_resolution::iterate_method_candidates(
@@ -2006,20 +2007,20 @@ impl Type {
2006 } 2007 }
2007 2008
2008 pub fn as_adt(&self) -> Option<Adt> { 2009 pub fn as_adt(&self) -> Option<Adt> {
2009 let (adt, _subst) = self.ty.value.as_adt()?; 2010 let (adt, _subst) = self.ty.as_adt()?;
2010 Some(adt.into()) 2011 Some(adt.into())
2011 } 2012 }
2012 2013
2013 pub fn as_dyn_trait(&self) -> Option<Trait> { 2014 pub fn as_dyn_trait(&self) -> Option<Trait> {
2014 self.ty.value.dyn_trait().map(Into::into) 2015 self.ty.dyn_trait().map(Into::into)
2015 } 2016 }
2016 2017
2017 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> { 2018 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
2018 self.ty.value.impl_trait_bounds(db).map(|it| { 2019 self.ty.impl_trait_bounds(db).map(|it| {
2019 it.into_iter() 2020 it.into_iter()
2020 .filter_map(|pred| match pred { 2021 .filter_map(|pred| match pred.skip_binders() {
2021 hir_ty::GenericPredicate::Implemented(trait_ref) => { 2022 hir_ty::WhereClause::Implemented(trait_ref) => {
2022 Some(Trait::from(trait_ref.trait_)) 2023 Some(Trait::from(trait_ref.hir_trait_id()))
2023 } 2024 }
2024 _ => None, 2025 _ => None,
2025 }) 2026 })
@@ -2028,14 +2029,11 @@ impl Type {
2028 } 2029 }
2029 2030
2030 pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> { 2031 pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> {
2031 self.ty.value.associated_type_parent_trait(db).map(Into::into) 2032 self.ty.associated_type_parent_trait(db).map(Into::into)
2032 } 2033 }
2033 2034
2034 fn derived(&self, ty: Ty) -> Type { 2035 fn derived(&self, ty: Ty) -> Type {
2035 Type { 2036 Type { krate: self.krate, env: self.env.clone(), ty }
2036 krate: self.krate,
2037 ty: InEnvironment { value: ty, environment: self.ty.environment.clone() },
2038 }
2039 } 2037 }
2040 2038
2041 pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) { 2039 pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) {
@@ -2056,14 +2054,17 @@ impl Type {
2056 fn walk_bounds( 2054 fn walk_bounds(
2057 db: &dyn HirDatabase, 2055 db: &dyn HirDatabase,
2058 type_: &Type, 2056 type_: &Type,
2059 bounds: &[GenericPredicate], 2057 bounds: &[QuantifiedWhereClause],
2060 cb: &mut impl FnMut(Type), 2058 cb: &mut impl FnMut(Type),
2061 ) { 2059 ) {
2062 for pred in bounds { 2060 for pred in bounds {
2063 match pred { 2061 match pred.skip_binders() {
2064 GenericPredicate::Implemented(trait_ref) => { 2062 WhereClause::Implemented(trait_ref) => {
2065 cb(type_.clone()); 2063 cb(type_.clone());
2066 walk_substs(db, type_, &trait_ref.substs, cb); 2064 // skip the self type. it's likely the type we just got the bounds from
2065 for ty in trait_ref.substitution.iter().skip(1) {
2066 walk_type(db, &type_.derived(ty.clone()), cb);
2067 }
2067 } 2068 }
2068 _ => (), 2069 _ => (),
2069 } 2070 }
@@ -2071,7 +2072,7 @@ impl Type {
2071 } 2072 }
2072 2073
2073 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { 2074 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
2074 let ty = type_.ty.value.strip_references(); 2075 let ty = type_.ty.strip_references();
2075 match ty.interned(&Interner) { 2076 match ty.interned(&Interner) {
2076 TyKind::Adt(..) => { 2077 TyKind::Adt(..) => {
2077 cb(type_.derived(ty.clone())); 2078 cb(type_.derived(ty.clone()));
@@ -2099,7 +2100,12 @@ impl Type {
2099 } 2100 }
2100 } 2101 }
2101 TyKind::Dyn(bounds) => { 2102 TyKind::Dyn(bounds) => {
2102 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); 2103 walk_bounds(
2104 db,
2105 &type_.derived(ty.clone()),
2106 bounds.bounds.skip_binders().interned(),
2107 cb,
2108 );
2103 } 2109 }
2104 2110
2105 TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { 2111 TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => {
@@ -2194,6 +2200,7 @@ pub enum ScopeDef {
2194 ImplSelfType(Impl), 2200 ImplSelfType(Impl),
2195 AdtSelfType(Adt), 2201 AdtSelfType(Adt),
2196 Local(Local), 2202 Local(Local),
2203 Label(Label),
2197 Unknown, 2204 Unknown,
2198} 2205}
2199 2206
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 15651bb22..1198e3f0b 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -839,6 +839,10 @@ impl<'a> SemanticsScope<'a> {
839 let parent = resolver.body_owner().unwrap(); 839 let parent = resolver.body_owner().unwrap();
840 ScopeDef::Local(Local { parent, pat_id }) 840 ScopeDef::Local(Local { parent, pat_id })
841 } 841 }
842 resolver::ScopeDef::Label(label_id) => {
843 let parent = resolver.body_owner().unwrap();
844 ScopeDef::Label(Label { parent, label_id })
845 }
842 }; 846 };
843 f(name, def) 847 f(name, def)
844 }) 848 })
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index c6ad5ecb5..762809fcd 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -195,12 +195,12 @@ impl SourceToDefCtx<'_, '_> {
195 &mut self, 195 &mut self,
196 src: InFile<ast::MacroRules>, 196 src: InFile<ast::MacroRules>,
197 ) -> Option<MacroDefId> { 197 ) -> Option<MacroDefId> {
198 let kind = MacroDefKind::Declarative; 198 let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value);
199 let ast_id = AstId::new(src.file_id, file_ast_id.upcast());
200 let kind = MacroDefKind::Declarative(ast_id);
199 let file_id = src.file_id.original_file(self.db.upcast()); 201 let file_id = src.file_id.original_file(self.db.upcast());
200 let krate = self.file_to_def(file_id).get(0).copied()?.krate(); 202 let krate = self.file_to_def(file_id).get(0).copied()?.krate();
201 let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); 203 Some(MacroDefId { krate, kind, local_inner: false })
202 let ast_id = Some(AstId::new(src.file_id, file_ast_id.upcast()));
203 Some(MacroDefId { krate, ast_id, kind, local_inner: false })
204 } 204 }
205 205
206 pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> { 206 pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> {
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index e4c84afbf..52a2bce9b 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -21,7 +21,7 @@ use crate::{
21 item_tree::{ItemTreeId, ItemTreeNode}, 21 item_tree::{ItemTreeId, ItemTreeNode},
22 nameres::ModuleSource, 22 nameres::ModuleSource,
23 path::{ModPath, PathKind}, 23 path::{ModPath, PathKind},
24 src::HasChildSource, 24 src::{HasChildSource, HasSource},
25 AdtId, AttrDefId, EnumId, GenericParamId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, 25 AdtId, AttrDefId, EnumId, GenericParamId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup,
26 VariantId, 26 VariantId,
27}; 27};
@@ -51,6 +51,12 @@ pub(crate) struct RawAttrs {
51#[derive(Default, Debug, Clone, PartialEq, Eq)] 51#[derive(Default, Debug, Clone, PartialEq, Eq)]
52pub struct Attrs(RawAttrs); 52pub struct Attrs(RawAttrs);
53 53
54#[derive(Debug, Clone, PartialEq, Eq)]
55pub struct AttrsWithOwner {
56 attrs: Attrs,
57 owner: AttrDefId,
58}
59
54impl ops::Deref for RawAttrs { 60impl ops::Deref for RawAttrs {
55 type Target = [Attr]; 61 type Target = [Attr];
56 62
@@ -73,6 +79,14 @@ impl ops::Deref for Attrs {
73 } 79 }
74} 80}
75 81
82impl ops::Deref for AttrsWithOwner {
83 type Target = Attrs;
84
85 fn deref(&self) -> &Attrs {
86 &self.attrs
87 }
88}
89
76impl RawAttrs { 90impl RawAttrs {
77 pub(crate) const EMPTY: Self = Self { entries: None }; 91 pub(crate) const EMPTY: Self = Self { entries: None };
78 92
@@ -169,77 +183,6 @@ impl RawAttrs {
169impl Attrs { 183impl Attrs {
170 pub const EMPTY: Self = Self(RawAttrs::EMPTY); 184 pub const EMPTY: Self = Self(RawAttrs::EMPTY);
171 185
172 pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs {
173 let raw_attrs = match def {
174 AttrDefId::ModuleId(module) => {
175 let def_map = module.def_map(db);
176 let mod_data = &def_map[module.local_id];
177 match mod_data.declaration_source(db) {
178 Some(it) => {
179 let raw_attrs = RawAttrs::from_attrs_owner(
180 db,
181 it.as_ref().map(|it| it as &dyn ast::AttrsOwner),
182 );
183 match mod_data.definition_source(db) {
184 InFile { file_id, value: ModuleSource::SourceFile(file) } => raw_attrs
185 .merge(RawAttrs::from_attrs_owner(db, InFile::new(file_id, &file))),
186 _ => raw_attrs,
187 }
188 }
189 None => RawAttrs::from_attrs_owner(
190 db,
191 mod_data.definition_source(db).as_ref().map(|src| match src {
192 ModuleSource::SourceFile(file) => file as &dyn ast::AttrsOwner,
193 ModuleSource::Module(module) => module as &dyn ast::AttrsOwner,
194 ModuleSource::BlockExpr(block) => block as &dyn ast::AttrsOwner,
195 }),
196 ),
197 }
198 }
199 AttrDefId::FieldId(it) => {
200 return db.fields_attrs(it.parent)[it.local_id].clone();
201 }
202 AttrDefId::EnumVariantId(it) => {
203 return db.variants_attrs(it.parent)[it.local_id].clone();
204 }
205 AttrDefId::AdtId(it) => match it {
206 AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db),
207 AdtId::EnumId(it) => attrs_from_item_tree(it.lookup(db).id, db),
208 AdtId::UnionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
209 },
210 AttrDefId::TraitId(it) => attrs_from_item_tree(it.lookup(db).id, db),
211 AttrDefId::MacroDefId(it) => {
212 it.ast_id.map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db))
213 }
214 AttrDefId::ImplId(it) => attrs_from_item_tree(it.lookup(db).id, db),
215 AttrDefId::ConstId(it) => attrs_from_item_tree(it.lookup(db).id, db),
216 AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db),
217 AttrDefId::FunctionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
218 AttrDefId::TypeAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db),
219 AttrDefId::GenericParamId(it) => match it {
220 GenericParamId::TypeParamId(it) => {
221 let src = it.parent.child_source(db);
222 RawAttrs::from_attrs_owner(
223 db,
224 src.with_value(
225 src.value[it.local_id].as_ref().either(|it| it as _, |it| it as _),
226 ),
227 )
228 }
229 GenericParamId::LifetimeParamId(it) => {
230 let src = it.parent.child_source(db);
231 RawAttrs::from_attrs_owner(db, src.with_value(&src.value[it.local_id]))
232 }
233 GenericParamId::ConstParamId(it) => {
234 let src = it.parent.child_source(db);
235 RawAttrs::from_attrs_owner(db, src.with_value(&src.value[it.local_id]))
236 }
237 },
238 };
239
240 raw_attrs.filter(db, def.krate(db))
241 }
242
243 pub(crate) fn variants_attrs_query( 186 pub(crate) fn variants_attrs_query(
244 db: &dyn DefDatabase, 187 db: &dyn DefDatabase,
245 e: EnumId, 188 e: EnumId,
@@ -280,13 +223,6 @@ impl Attrs {
280 Arc::new(res) 223 Arc::new(res)
281 } 224 }
282 225
283 /// Constructs a map that maps the lowered `Attr`s in this `Attrs` back to its original syntax nodes.
284 ///
285 /// `owner` must be the original owner of the attributes.
286 pub fn source_map(&self, owner: &dyn ast::AttrsOwner) -> AttrSourceMap {
287 AttrSourceMap { attrs: collect_attrs(owner).collect() }
288 }
289
290 pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { 226 pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
291 AttrQuery { attrs: self, key } 227 AttrQuery { attrs: self, key }
292 } 228 }
@@ -343,6 +279,180 @@ impl Attrs {
343 } 279 }
344} 280}
345 281
282impl AttrsWithOwner {
283 pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Self {
284 // FIXME: this should use `Trace` to avoid duplication in `source_map` below
285 let raw_attrs = match def {
286 AttrDefId::ModuleId(module) => {
287 let def_map = module.def_map(db);
288 let mod_data = &def_map[module.local_id];
289 match mod_data.declaration_source(db) {
290 Some(it) => {
291 let raw_attrs = RawAttrs::from_attrs_owner(
292 db,
293 it.as_ref().map(|it| it as &dyn ast::AttrsOwner),
294 );
295 match mod_data.definition_source(db) {
296 InFile { file_id, value: ModuleSource::SourceFile(file) } => raw_attrs
297 .merge(RawAttrs::from_attrs_owner(db, InFile::new(file_id, &file))),
298 _ => raw_attrs,
299 }
300 }
301 None => RawAttrs::from_attrs_owner(
302 db,
303 mod_data.definition_source(db).as_ref().map(|src| match src {
304 ModuleSource::SourceFile(file) => file as &dyn ast::AttrsOwner,
305 ModuleSource::Module(module) => module as &dyn ast::AttrsOwner,
306 ModuleSource::BlockExpr(block) => block as &dyn ast::AttrsOwner,
307 }),
308 ),
309 }
310 }
311 AttrDefId::FieldId(it) => {
312 return Self { attrs: db.fields_attrs(it.parent)[it.local_id].clone(), owner: def };
313 }
314 AttrDefId::EnumVariantId(it) => {
315 return Self {
316 attrs: db.variants_attrs(it.parent)[it.local_id].clone(),
317 owner: def,
318 };
319 }
320 AttrDefId::AdtId(it) => match it {
321 AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db),
322 AdtId::EnumId(it) => attrs_from_item_tree(it.lookup(db).id, db),
323 AdtId::UnionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
324 },
325 AttrDefId::TraitId(it) => attrs_from_item_tree(it.lookup(db).id, db),
326 AttrDefId::MacroDefId(it) => it
327 .ast_id()
328 .left()
329 .map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db)),
330 AttrDefId::ImplId(it) => attrs_from_item_tree(it.lookup(db).id, db),
331 AttrDefId::ConstId(it) => attrs_from_item_tree(it.lookup(db).id, db),
332 AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db),
333 AttrDefId::FunctionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
334 AttrDefId::TypeAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db),
335 AttrDefId::GenericParamId(it) => match it {
336 GenericParamId::TypeParamId(it) => {
337 let src = it.parent.child_source(db);
338 RawAttrs::from_attrs_owner(
339 db,
340 src.with_value(
341 src.value[it.local_id].as_ref().either(|it| it as _, |it| it as _),
342 ),
343 )
344 }
345 GenericParamId::LifetimeParamId(it) => {
346 let src = it.parent.child_source(db);
347 RawAttrs::from_attrs_owner(db, src.with_value(&src.value[it.local_id]))
348 }
349 GenericParamId::ConstParamId(it) => {
350 let src = it.parent.child_source(db);
351 RawAttrs::from_attrs_owner(db, src.with_value(&src.value[it.local_id]))
352 }
353 },
354 };
355
356 let attrs = raw_attrs.filter(db, def.krate(db));
357 Self { attrs, owner: def }
358 }
359
360 pub fn source_map(&self, db: &dyn DefDatabase) -> AttrSourceMap {
361 let owner = match self.owner {
362 AttrDefId::ModuleId(module) => {
363 // Modules can have 2 attribute owners (the `mod x;` item, and the module file itself).
364
365 let def_map = module.def_map(db);
366 let mod_data = &def_map[module.local_id];
367 let attrs = match mod_data.declaration_source(db) {
368 Some(it) => {
369 let mut attrs: Vec<_> = collect_attrs(&it.value as &dyn ast::AttrsOwner)
370 .map(|attr| InFile::new(it.file_id, attr))
371 .collect();
372 if let InFile { file_id, value: ModuleSource::SourceFile(file) } =
373 mod_data.definition_source(db)
374 {
375 attrs.extend(
376 collect_attrs(&file as &dyn ast::AttrsOwner)
377 .map(|attr| InFile::new(file_id, attr)),
378 )
379 }
380 attrs
381 }
382 None => {
383 let InFile { file_id, value } = mod_data.definition_source(db);
384 match &value {
385 ModuleSource::SourceFile(file) => {
386 collect_attrs(file as &dyn ast::AttrsOwner)
387 }
388 ModuleSource::Module(module) => {
389 collect_attrs(module as &dyn ast::AttrsOwner)
390 }
391 ModuleSource::BlockExpr(block) => {
392 collect_attrs(block as &dyn ast::AttrsOwner)
393 }
394 }
395 .map(|attr| InFile::new(file_id, attr))
396 .collect()
397 }
398 };
399 return AttrSourceMap { attrs };
400 }
401 AttrDefId::FieldId(id) => {
402 id.parent.child_source(db).map(|source| match &source[id.local_id] {
403 Either::Left(field) => ast::AttrsOwnerNode::new(field.clone()),
404 Either::Right(field) => ast::AttrsOwnerNode::new(field.clone()),
405 })
406 }
407 AttrDefId::AdtId(adt) => match adt {
408 AdtId::StructId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
409 AdtId::UnionId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
410 AdtId::EnumId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
411 },
412 AttrDefId::FunctionId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
413 AttrDefId::EnumVariantId(id) => id
414 .parent
415 .child_source(db)
416 .map(|source| ast::AttrsOwnerNode::new(source[id.local_id].clone())),
417 AttrDefId::StaticId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
418 AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
419 AttrDefId::TraitId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
420 AttrDefId::TypeAliasId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
421 AttrDefId::MacroDefId(id) => match id.ast_id() {
422 Either::Left(it) => {
423 it.with_value(ast::AttrsOwnerNode::new(it.to_node(db.upcast())))
424 }
425 Either::Right(it) => {
426 it.with_value(ast::AttrsOwnerNode::new(it.to_node(db.upcast())))
427 }
428 },
429 AttrDefId::ImplId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
430 AttrDefId::GenericParamId(id) => match id {
431 GenericParamId::TypeParamId(id) => {
432 id.parent.child_source(db).map(|source| match &source[id.local_id] {
433 Either::Left(id) => ast::AttrsOwnerNode::new(id.clone()),
434 Either::Right(id) => ast::AttrsOwnerNode::new(id.clone()),
435 })
436 }
437 GenericParamId::LifetimeParamId(id) => id
438 .parent
439 .child_source(db)
440 .map(|source| ast::AttrsOwnerNode::new(source[id.local_id].clone())),
441 GenericParamId::ConstParamId(id) => id
442 .parent
443 .child_source(db)
444 .map(|source| ast::AttrsOwnerNode::new(source[id.local_id].clone())),
445 },
446 };
447
448 AttrSourceMap {
449 attrs: collect_attrs(&owner.value)
450 .map(|attr| InFile::new(owner.file_id, attr))
451 .collect(),
452 }
453 }
454}
455
346fn inner_attributes( 456fn inner_attributes(
347 syntax: &SyntaxNode, 457 syntax: &SyntaxNode,
348) -> Option<(impl Iterator<Item = ast::Attr>, impl Iterator<Item = ast::Comment>)> { 458) -> Option<(impl Iterator<Item = ast::Attr>, impl Iterator<Item = ast::Comment>)> {
@@ -379,7 +489,7 @@ fn inner_attributes(
379} 489}
380 490
381pub struct AttrSourceMap { 491pub struct AttrSourceMap {
382 attrs: Vec<Either<ast::Attr, ast::Comment>>, 492 attrs: Vec<InFile<Either<ast::Attr, ast::Comment>>>,
383} 493}
384 494
385impl AttrSourceMap { 495impl AttrSourceMap {
@@ -389,10 +499,11 @@ impl AttrSourceMap {
389 /// 499 ///
390 /// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of 500 /// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of
391 /// the attribute represented by `Attr`. 501 /// the attribute represented by `Attr`.
392 pub fn source_of(&self, attr: &Attr) -> &Either<ast::Attr, ast::Comment> { 502 pub fn source_of(&self, attr: &Attr) -> InFile<&Either<ast::Attr, ast::Comment>> {
393 self.attrs 503 self.attrs
394 .get(attr.index as usize) 504 .get(attr.index as usize)
395 .unwrap_or_else(|| panic!("cannot find `Attr` at index {}", attr.index)) 505 .unwrap_or_else(|| panic!("cannot find `Attr` at index {}", attr.index))
506 .as_ref()
396 } 507 }
397} 508}
398 509
@@ -414,7 +525,7 @@ pub enum AttrInput {
414impl Attr { 525impl Attr {
415 fn from_src(ast: ast::Attr, hygiene: &Hygiene, index: u32) -> Option<Attr> { 526 fn from_src(ast: ast::Attr, hygiene: &Hygiene, index: u32) -> Option<Attr> {
416 let path = ModPath::from_src(ast.path()?, hygiene)?; 527 let path = ModPath::from_src(ast.path()?, hygiene)?;
417 let input = if let Some(lit) = ast.literal() { 528 let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() {
418 let value = match lit.kind() { 529 let value = match lit.kind() {
419 ast::LiteralKind::String(string) => string.value()?.into(), 530 ast::LiteralKind::String(string) => string.value()?.into(),
420 _ => lit.syntax().first_token()?.text().trim_matches('"').into(), 531 _ => lit.syntax().first_token()?.text().trim_matches('"').into(),
@@ -428,18 +539,6 @@ impl Attr {
428 Some(Attr { index, path, input }) 539 Some(Attr { index, path, input })
429 } 540 }
430 541
431 /// Maps this lowered `Attr` back to its original syntax node.
432 ///
433 /// `owner` must be the original owner of the attribute.
434 ///
435 /// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of
436 /// the attribute represented by `Attr`.
437 pub fn to_src(&self, owner: &dyn ast::AttrsOwner) -> Either<ast::Attr, ast::Comment> {
438 collect_attrs(owner).nth(self.index as usize).unwrap_or_else(|| {
439 panic!("cannot find `Attr` at index {} in {}", self.index, owner.syntax())
440 })
441 }
442
443 /// Parses this attribute as a `#[derive]`, returns an iterator that yields all contained paths 542 /// Parses this attribute as a `#[derive]`, returns an iterator that yields all contained paths
444 /// to derive macros. 543 /// to derive macros.
445 /// 544 ///
@@ -539,7 +638,7 @@ fn collect_attrs(
539 owner: &dyn ast::AttrsOwner, 638 owner: &dyn ast::AttrsOwner,
540) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> { 639) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> {
541 let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) 640 let (inner_attrs, inner_docs) = inner_attributes(owner.syntax())
542 .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs)))); 641 .map_or((None, None), |(attrs, docs)| (Some(attrs), Some(docs)));
543 642
544 let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none()); 643 let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none());
545 let attrs = outer_attrs 644 let attrs = outer_attrs
diff --git a/crates/hir_def/src/body/scope.rs b/crates/hir_def/src/body/scope.rs
index 1bbb54fc6..bd7005ca6 100644
--- a/crates/hir_def/src/body/scope.rs
+++ b/crates/hir_def/src/body/scope.rs
@@ -8,7 +8,7 @@ use rustc_hash::FxHashMap;
8use crate::{ 8use crate::{
9 body::Body, 9 body::Body,
10 db::DefDatabase, 10 db::DefDatabase,
11 expr::{Expr, ExprId, Pat, PatId, Statement}, 11 expr::{Expr, ExprId, LabelId, Pat, PatId, Statement},
12 BlockId, DefWithBodyId, 12 BlockId, DefWithBodyId,
13}; 13};
14 14
@@ -40,6 +40,7 @@ impl ScopeEntry {
40pub struct ScopeData { 40pub struct ScopeData {
41 parent: Option<ScopeId>, 41 parent: Option<ScopeId>,
42 block: Option<BlockId>, 42 block: Option<BlockId>,
43 label: Option<(LabelId, Name)>,
43 entries: Vec<ScopeEntry>, 44 entries: Vec<ScopeEntry>,
44} 45}
45 46
@@ -67,6 +68,11 @@ impl ExprScopes {
67 self.scopes[scope].block 68 self.scopes[scope].block
68 } 69 }
69 70
71 /// If `scope` refers to a labeled expression scope, returns the corresponding `Label`.
72 pub fn label(&self, scope: ScopeId) -> Option<(LabelId, Name)> {
73 self.scopes[scope].label.clone()
74 }
75
70 pub fn scope_chain(&self, scope: Option<ScopeId>) -> impl Iterator<Item = ScopeId> + '_ { 76 pub fn scope_chain(&self, scope: Option<ScopeId>) -> impl Iterator<Item = ScopeId> + '_ {
71 std::iter::successors(scope, move |&scope| self.scopes[scope].parent) 77 std::iter::successors(scope, move |&scope| self.scopes[scope].parent)
72 } 78 }
@@ -85,15 +91,34 @@ impl ExprScopes {
85 } 91 }
86 92
87 fn root_scope(&mut self) -> ScopeId { 93 fn root_scope(&mut self) -> ScopeId {
88 self.scopes.alloc(ScopeData { parent: None, block: None, entries: vec![] }) 94 self.scopes.alloc(ScopeData { parent: None, block: None, label: None, entries: vec![] })
89 } 95 }
90 96
91 fn new_scope(&mut self, parent: ScopeId) -> ScopeId { 97 fn new_scope(&mut self, parent: ScopeId) -> ScopeId {
92 self.scopes.alloc(ScopeData { parent: Some(parent), block: None, entries: vec![] }) 98 self.scopes.alloc(ScopeData {
99 parent: Some(parent),
100 block: None,
101 label: None,
102 entries: vec![],
103 })
93 } 104 }
94 105
95 fn new_block_scope(&mut self, parent: ScopeId, block: BlockId) -> ScopeId { 106 fn new_labeled_scope(&mut self, parent: ScopeId, label: Option<(LabelId, Name)>) -> ScopeId {
96 self.scopes.alloc(ScopeData { parent: Some(parent), block: Some(block), entries: vec![] }) 107 self.scopes.alloc(ScopeData { parent: Some(parent), block: None, label, entries: vec![] })
108 }
109
110 fn new_block_scope(
111 &mut self,
112 parent: ScopeId,
113 block: BlockId,
114 label: Option<(LabelId, Name)>,
115 ) -> ScopeId {
116 self.scopes.alloc(ScopeData {
117 parent: Some(parent),
118 block: Some(block),
119 label,
120 entries: vec![],
121 })
97 } 122 }
98 123
99 fn add_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) { 124 fn add_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) {
@@ -144,21 +169,33 @@ fn compute_block_scopes(
144} 169}
145 170
146fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) { 171fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) {
172 let make_label =
173 |label: &Option<_>| label.map(|label| (label, body.labels[label].name.clone()));
174
147 scopes.set_scope(expr, scope); 175 scopes.set_scope(expr, scope);
148 match &body[expr] { 176 match &body[expr] {
149 Expr::Block { statements, tail, id, .. } => { 177 Expr::Block { statements, tail, id, label } => {
150 let scope = scopes.new_block_scope(scope, *id); 178 let scope = scopes.new_block_scope(scope, *id, make_label(label));
151 // Overwrite the old scope for the block expr, so that every block scope can be found 179 // Overwrite the old scope for the block expr, so that every block scope can be found
152 // via the block itself (important for blocks that only contain items, no expressions). 180 // via the block itself (important for blocks that only contain items, no expressions).
153 scopes.set_scope(expr, scope); 181 scopes.set_scope(expr, scope);
154 compute_block_scopes(&statements, *tail, body, scopes, scope); 182 compute_block_scopes(statements, *tail, body, scopes, scope);
155 } 183 }
156 Expr::For { iterable, pat, body: body_expr, .. } => { 184 Expr::For { iterable, pat, body: body_expr, label } => {
157 compute_expr_scopes(*iterable, body, scopes, scope); 185 compute_expr_scopes(*iterable, body, scopes, scope);
158 let scope = scopes.new_scope(scope); 186 let scope = scopes.new_labeled_scope(scope, make_label(label));
159 scopes.add_bindings(body, scope, *pat); 187 scopes.add_bindings(body, scope, *pat);
160 compute_expr_scopes(*body_expr, body, scopes, scope); 188 compute_expr_scopes(*body_expr, body, scopes, scope);
161 } 189 }
190 Expr::While { condition, body: body_expr, label } => {
191 let scope = scopes.new_labeled_scope(scope, make_label(label));
192 compute_expr_scopes(*condition, body, scopes, scope);
193 compute_expr_scopes(*body_expr, body, scopes, scope);
194 }
195 Expr::Loop { body: body_expr, label } => {
196 let scope = scopes.new_labeled_scope(scope, make_label(label));
197 compute_expr_scopes(*body_expr, body, scopes, scope);
198 }
162 Expr::Lambda { args, body: body_expr, .. } => { 199 Expr::Lambda { args, body: body_expr, .. } => {
163 let scope = scopes.new_scope(scope); 200 let scope = scopes.new_scope(scope);
164 scopes.add_params_bindings(body, scope, &args); 201 scopes.add_params_bindings(body, scope, &args);
diff --git a/crates/hir_def/src/builtin_attr.rs b/crates/hir_def/src/builtin_attr.rs
index 2e989c504..d5d7f0f47 100644
--- a/crates/hir_def/src/builtin_attr.rs
+++ b/crates/hir_def/src/builtin_attr.rs
@@ -34,9 +34,12 @@ macro_rules! rustc_attr {
34 }; 34 };
35} 35}
36 36
37/// Attributes that have a special meaning to rustc or rustdoc. 37/// Built-in macro-like attributes.
38pub const EXTRA_ATTRIBUTES: &[BuiltinAttribute] = &["test", "bench"];
39
40/// "Inert" built-in attributes that have a special meaning to rustc or rustdoc.
38#[rustfmt::skip] 41#[rustfmt::skip]
39pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ 42pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
40 // ========================================================================== 43 // ==========================================================================
41 // Stable attributes: 44 // Stable attributes:
42 // ========================================================================== 45 // ==========================================================================
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs
index 276caf5b3..53df85089 100644
--- a/crates/hir_def/src/db.rs
+++ b/crates/hir_def/src/db.rs
@@ -8,7 +8,7 @@ use syntax::SmolStr;
8 8
9use crate::{ 9use crate::{
10 adt::{EnumData, StructData}, 10 adt::{EnumData, StructData},
11 attr::Attrs, 11 attr::{Attrs, AttrsWithOwner},
12 body::{scope::ExprScopes, Body, BodySourceMap}, 12 body::{scope::ExprScopes, Body, BodySourceMap},
13 data::{ConstData, FunctionData, ImplData, StaticData, TraitData, TypeAliasData}, 13 data::{ConstData, FunctionData, ImplData, StaticData, TraitData, TypeAliasData},
14 generics::GenericParams, 14 generics::GenericParams,
@@ -120,8 +120,8 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
120 #[salsa::invoke(Attrs::fields_attrs_query)] 120 #[salsa::invoke(Attrs::fields_attrs_query)]
121 fn fields_attrs(&self, def: VariantId) -> Arc<ArenaMap<LocalFieldId, Attrs>>; 121 fn fields_attrs(&self, def: VariantId) -> Arc<ArenaMap<LocalFieldId, Attrs>>;
122 122
123 #[salsa::invoke(Attrs::attrs_query)] 123 #[salsa::invoke(AttrsWithOwner::attrs_query)]
124 fn attrs(&self, def: AttrDefId) -> Attrs; 124 fn attrs(&self, def: AttrDefId) -> AttrsWithOwner;
125 125
126 #[salsa::invoke(LangItems::crate_lang_items_query)] 126 #[salsa::invoke(LangItems::crate_lang_items_query)]
127 fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>; 127 fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>;
diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs
index 369bc3350..960cabb5f 100644
--- a/crates/hir_def/src/import_map.rs
+++ b/crates/hir_def/src/import_map.rs
@@ -912,10 +912,10 @@ mod tests {
912 dep::fmt (t) 912 dep::fmt (t)
913 dep::format (f) 913 dep::format (f)
914 dep::Fmt (v) 914 dep::Fmt (v)
915 dep::fmt::Display (t) 915 dep::Fmt (m)
916 dep::Fmt (t) 916 dep::Fmt (t)
917 dep::fmt::Display::fmt (a) 917 dep::fmt::Display::fmt (a)
918 dep::Fmt (m) 918 dep::fmt::Display (t)
919 "#]], 919 "#]],
920 ); 920 );
921 921
@@ -926,9 +926,9 @@ mod tests {
926 expect![[r#" 926 expect![[r#"
927 dep::fmt (t) 927 dep::fmt (t)
928 dep::Fmt (v) 928 dep::Fmt (v)
929 dep::Fmt (m)
929 dep::Fmt (t) 930 dep::Fmt (t)
930 dep::fmt::Display::fmt (a) 931 dep::fmt::Display::fmt (a)
931 dep::Fmt (m)
932 "#]], 932 "#]],
933 ); 933 );
934 934
@@ -939,10 +939,10 @@ mod tests {
939 expect![[r#" 939 expect![[r#"
940 dep::fmt (t) 940 dep::fmt (t)
941 dep::Fmt (v) 941 dep::Fmt (v)
942 dep::fmt::Display (t) 942 dep::Fmt (m)
943 dep::Fmt (t) 943 dep::Fmt (t)
944 dep::fmt::Display::fmt (a) 944 dep::fmt::Display::fmt (a)
945 dep::Fmt (m) 945 dep::fmt::Display (t)
946 "#]], 946 "#]],
947 ); 947 );
948 } 948 }
@@ -980,10 +980,10 @@ mod tests {
980 expect![[r#" 980 expect![[r#"
981 dep::fmt (t) 981 dep::fmt (t)
982 dep::Fmt (v) 982 dep::Fmt (v)
983 dep::fmt::Display (t) 983 dep::Fmt (m)
984 dep::Fmt (t) 984 dep::Fmt (t)
985 dep::fmt::Display::fmt (a) 985 dep::fmt::Display::fmt (a)
986 dep::Fmt (m) 986 dep::fmt::Display (t)
987 "#]], 987 "#]],
988 ); 988 );
989 989
@@ -994,9 +994,9 @@ mod tests {
994 expect![[r#" 994 expect![[r#"
995 dep::fmt (t) 995 dep::fmt (t)
996 dep::Fmt (v) 996 dep::Fmt (v)
997 dep::Fmt (m)
997 dep::Fmt (t) 998 dep::Fmt (t)
998 dep::fmt::Display::fmt (a) 999 dep::fmt::Display::fmt (a)
999 dep::Fmt (m)
1000 "#]], 1000 "#]],
1001 ); 1001 );
1002 } 1002 }
@@ -1058,8 +1058,8 @@ mod tests {
1058 Query::new("".to_string()).limit(2), 1058 Query::new("".to_string()).limit(2),
1059 expect![[r#" 1059 expect![[r#"
1060 dep::fmt (t) 1060 dep::fmt (t)
1061 dep::Fmt (t)
1062 dep::Fmt (m) 1061 dep::Fmt (m)
1062 dep::Fmt (t)
1063 dep::Fmt (v) 1063 dep::Fmt (v)
1064 "#]], 1064 "#]],
1065 ); 1065 );
diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs
index aafd73b60..f3ebe7c72 100644
--- a/crates/hir_def/src/item_scope.rs
+++ b/crates/hir_def/src/item_scope.rs
@@ -252,7 +252,7 @@ impl ItemScope {
252 .for_each(|vis| *vis = Visibility::Module(this_module)); 252 .for_each(|vis| *vis = Visibility::Module(this_module));
253 253
254 for (mac, vis) in self.macros.values_mut() { 254 for (mac, vis) in self.macros.values_mut() {
255 if let MacroDefKind::ProcMacro(_) = mac.kind { 255 if let MacroDefKind::ProcMacro(..) = mac.kind {
256 // FIXME: Technically this is insufficient since reexports of proc macros are also 256 // FIXME: Technically this is insufficient since reexports of proc macros are also
257 // forbidden. Practically nobody does that. 257 // forbidden. Practically nobody does that.
258 continue; 258 continue;
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 5f5b7151a..ae2475b4e 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -115,6 +115,10 @@ impl ItemTree {
115 // still need to collect inner items. 115 // still need to collect inner items.
116 ctx.lower_inner_items(stmt.syntax()) 116 ctx.lower_inner_items(stmt.syntax())
117 }, 117 },
118 ast::Item(item) => {
119 // Macros can expand to stmt and other item, and we add it as top level item
120 ctx.lower_single_item(item)
121 },
118 _ => { 122 _ => {
119 panic!("cannot create item tree from {:?} {}", syntax, syntax); 123 panic!("cannot create item tree from {:?} {}", syntax, syntax);
120 }, 124 },
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 3f558edd8..d3fe1ce1e 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -87,6 +87,14 @@ impl Ctx {
87 self.tree 87 self.tree
88 } 88 }
89 89
90 pub(super) fn lower_single_item(mut self, item: ast::Item) -> ItemTree {
91 self.tree.top_level = self
92 .lower_mod_item(&item, false)
93 .map(|item| item.0)
94 .unwrap_or_else(|| Default::default());
95 self.tree
96 }
97
90 pub(super) fn lower_inner_items(mut self, within: &SyntaxNode) -> ItemTree { 98 pub(super) fn lower_inner_items(mut self, within: &SyntaxNode) -> ItemTree {
91 self.collect_inner_items(within); 99 self.collect_inner_items(within);
92 self.tree 100 self.tree
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index 6758411a0..c9e07de86 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -76,7 +76,11 @@ use stdx::impl_from;
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 76#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
77pub struct ModuleId { 77pub struct ModuleId {
78 krate: CrateId, 78 krate: CrateId,
79 /// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the
80 /// `BlockId` of that block expression. If `None`, this module is part of the crate-level
81 /// `DefMap` of `krate`.
79 block: Option<BlockId>, 82 block: Option<BlockId>,
83 /// The module's ID in its originating `DefMap`.
80 pub local_id: LocalModuleId, 84 pub local_id: LocalModuleId,
81} 85}
82 86
@@ -87,7 +91,7 @@ impl ModuleId {
87 db.block_def_map(block).unwrap_or_else(|| { 91 db.block_def_map(block).unwrap_or_else(|| {
88 // NOTE: This should be unreachable - all `ModuleId`s come from their `DefMap`s, 92 // NOTE: This should be unreachable - all `ModuleId`s come from their `DefMap`s,
89 // so the `DefMap` here must exist. 93 // so the `DefMap` here must exist.
90 panic!("no `block_def_map` for `ModuleId` {:?}", self); 94 unreachable!("no `block_def_map` for `ModuleId` {:?}", self);
91 }) 95 })
92 } 96 }
93 None => db.crate_def_map(self.krate), 97 None => db.crate_def_map(self.krate),
@@ -650,7 +654,7 @@ fn macro_call_as_call_id(
650) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> { 654) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
651 let def: MacroDefId = resolver(call.path.clone()).ok_or(UnresolvedMacro)?; 655 let def: MacroDefId = resolver(call.path.clone()).ok_or(UnresolvedMacro)?;
652 656
653 let res = if let MacroDefKind::BuiltInEager(_) = def.kind { 657 let res = if let MacroDefKind::BuiltInEager(..) = def.kind {
654 let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast())); 658 let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast()));
655 let hygiene = Hygiene::new(db.upcast(), call.ast_id.file_id); 659 let hygiene = Hygiene::new(db.upcast(), call.ast_id.file_id);
656 660
@@ -669,7 +673,7 @@ fn macro_call_as_call_id(
669 Ok(res) 673 Ok(res)
670} 674}
671 675
672fn item_attr_as_call_id( 676fn derive_macro_as_call_id(
673 item_attr: &AstIdWithPath<ast::Item>, 677 item_attr: &AstIdWithPath<ast::Item>,
674 db: &dyn db::DefDatabase, 678 db: &dyn db::DefDatabase,
675 krate: CrateId, 679 krate: CrateId,
@@ -681,7 +685,7 @@ fn item_attr_as_call_id(
681 .as_lazy_macro( 685 .as_lazy_macro(
682 db.upcast(), 686 db.upcast(),
683 krate, 687 krate,
684 MacroCallKind::Attr(item_attr.ast_id, last_segment.to_string()), 688 MacroCallKind::Derive(item_attr.ast_id, last_segment.to_string()),
685 ) 689 )
686 .into(); 690 .into();
687 Ok(res) 691 Ok(res)
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index c97be584e..0d3a0b54f 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -53,11 +53,12 @@ mod path_resolution;
53 53
54#[cfg(test)] 54#[cfg(test)]
55mod tests; 55mod tests;
56mod proc_macro;
56 57
57use std::sync::Arc; 58use std::sync::Arc;
58 59
59use base_db::{CrateId, Edition, FileId}; 60use base_db::{CrateId, Edition, FileId};
60use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile}; 61use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId};
61use la_arena::Arena; 62use la_arena::Arena;
62use profile::Count; 63use profile::Count;
63use rustc_hash::FxHashMap; 64use rustc_hash::FxHashMap;
@@ -73,6 +74,8 @@ use crate::{
73 AstId, BlockId, BlockLoc, LocalModuleId, ModuleDefId, ModuleId, 74 AstId, BlockId, BlockLoc, LocalModuleId, ModuleDefId, ModuleId,
74}; 75};
75 76
77use self::proc_macro::ProcMacroDef;
78
76/// Contains the results of (early) name resolution. 79/// Contains the results of (early) name resolution.
77/// 80///
78/// A `DefMap` stores the module tree and the definitions that are in scope in every module after 81/// A `DefMap` stores the module tree and the definitions that are in scope in every module after
@@ -95,6 +98,12 @@ pub struct DefMap {
95 prelude: Option<ModuleId>, 98 prelude: Option<ModuleId>,
96 extern_prelude: FxHashMap<Name, ModuleDefId>, 99 extern_prelude: FxHashMap<Name, ModuleDefId>,
97 100
101 /// Side table with additional proc. macro info, for use by name resolution in downstream
102 /// crates.
103 ///
104 /// (the primary purpose is to resolve derive helpers)
105 exported_proc_macros: FxHashMap<MacroDefId, ProcMacroDef>,
106
98 edition: Edition, 107 edition: Edition,
99 diagnostics: Vec<DefDiagnostic>, 108 diagnostics: Vec<DefDiagnostic>,
100} 109}
@@ -237,6 +246,7 @@ impl DefMap {
237 krate, 246 krate,
238 edition, 247 edition,
239 extern_prelude: FxHashMap::default(), 248 extern_prelude: FxHashMap::default(),
249 exported_proc_macros: FxHashMap::default(),
240 prelude: None, 250 prelude: None,
241 root, 251 root,
242 modules, 252 modules,
@@ -565,7 +575,7 @@ mod diagnostics {
565 let node = ast.to_node(db.upcast()); 575 let node = ast.to_node(db.upcast());
566 (ast.file_id, SyntaxNodePtr::from(AstPtr::new(&node)), None) 576 (ast.file_id, SyntaxNodePtr::from(AstPtr::new(&node)), None)
567 } 577 }
568 MacroCallKind::Attr(ast, name) => { 578 MacroCallKind::Derive(ast, name) => {
569 let node = ast.to_node(db.upcast()); 579 let node = ast.to_node(db.upcast());
570 580
571 // Compute the precise location of the macro name's token in the derive 581 // Compute the precise location of the macro name's token in the derive
@@ -621,7 +631,7 @@ mod diagnostics {
621 let node = ast.to_node(db.upcast()); 631 let node = ast.to_node(db.upcast());
622 (ast.file_id, SyntaxNodePtr::from(AstPtr::new(&node))) 632 (ast.file_id, SyntaxNodePtr::from(AstPtr::new(&node)))
623 } 633 }
624 MacroCallKind::Attr(ast, _) => { 634 MacroCallKind::Derive(ast, _) => {
625 let node = ast.to_node(db.upcast()); 635 let node = ast.to_node(db.upcast());
626 (ast.file_id, SyntaxNodePtr::from(AstPtr::new(&node))) 636 (ast.file_id, SyntaxNodePtr::from(AstPtr::new(&node)))
627 } 637 }
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index d0fefb5af..28b73c3a1 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -18,12 +18,11 @@ use hir_expand::{
18use hir_expand::{InFile, MacroCallLoc}; 18use hir_expand::{InFile, MacroCallLoc};
19use rustc_hash::{FxHashMap, FxHashSet}; 19use rustc_hash::{FxHashMap, FxHashSet};
20use syntax::ast; 20use syntax::ast;
21use tt::{Leaf, TokenTree};
22 21
23use crate::{ 22use crate::{
24 attr::Attrs, 23 attr::Attrs,
25 db::DefDatabase, 24 db::DefDatabase,
26 item_attr_as_call_id, 25 derive_macro_as_call_id,
27 item_scope::{ImportType, PerNsGlobImports}, 26 item_scope::{ImportType, PerNsGlobImports},
28 item_tree::{ 27 item_tree::{
29 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, 28 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind,
@@ -42,6 +41,8 @@ use crate::{
42 UnresolvedMacro, 41 UnresolvedMacro,
43}; 42};
44 43
44use super::proc_macro::ProcMacroDef;
45
45const GLOB_RECURSION_LIMIT: usize = 100; 46const GLOB_RECURSION_LIMIT: usize = 100;
46const EXPANSION_DEPTH_LIMIT: usize = 128; 47const EXPANSION_DEPTH_LIMIT: usize = 128;
47const FIXED_POINT_LIMIT: usize = 8192; 48const FIXED_POINT_LIMIT: usize = 8192;
@@ -353,24 +354,23 @@ impl DefCollector<'_> {
353 /// use a dummy expander that always errors. This comes with the drawback of macros potentially 354 /// use a dummy expander that always errors. This comes with the drawback of macros potentially
354 /// going out of sync with what the build system sees (since we resolve using VFS state, but 355 /// going out of sync with what the build system sees (since we resolve using VFS state, but
355 /// Cargo builds only on-disk files). We could and probably should add diagnostics for that. 356 /// Cargo builds only on-disk files). We could and probably should add diagnostics for that.
356 fn resolve_proc_macro(&mut self, name: &Name) { 357 fn export_proc_macro(&mut self, def: ProcMacroDef, ast_id: AstId<ast::Fn>) {
357 self.exports_proc_macros = true; 358 self.exports_proc_macros = true;
358 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) { 359 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == &def.name) {
359 Some((_, expander)) => MacroDefId { 360 Some((_, expander)) => MacroDefId {
360 ast_id: None,
361 krate: self.def_map.krate, 361 krate: self.def_map.krate,
362 kind: MacroDefKind::ProcMacro(*expander), 362 kind: MacroDefKind::ProcMacro(*expander, ast_id),
363 local_inner: false, 363 local_inner: false,
364 }, 364 },
365 None => MacroDefId { 365 None => MacroDefId {
366 ast_id: None,
367 krate: self.def_map.krate, 366 krate: self.def_map.krate,
368 kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate)), 367 kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate), ast_id),
369 local_inner: false, 368 local_inner: false,
370 }, 369 },
371 }; 370 };
372 371
373 self.define_proc_macro(name.clone(), macro_def); 372 self.define_proc_macro(def.name.clone(), macro_def);
373 self.def_map.exported_proc_macros.insert(macro_def, def);
374 } 374 }
375 375
376 /// Define a macro with `macro_rules`. 376 /// Define a macro with `macro_rules`.
@@ -820,8 +820,8 @@ impl DefCollector<'_> {
820 true 820 true
821 }); 821 });
822 attribute_macros.retain(|directive| { 822 attribute_macros.retain(|directive| {
823 match item_attr_as_call_id(&directive.ast_id, self.db, self.def_map.krate, |path| { 823 match derive_macro_as_call_id(&directive.ast_id, self.db, self.def_map.krate, |path| {
824 self.resolve_attribute_macro(&directive, &path) 824 self.resolve_derive_macro(&directive, &path)
825 }) { 825 }) {
826 Ok(call_id) => { 826 Ok(call_id) => {
827 resolved.push((directive.module_id, call_id, 0)); 827 resolved.push((directive.module_id, call_id, 0));
@@ -844,7 +844,7 @@ impl DefCollector<'_> {
844 res 844 res
845 } 845 }
846 846
847 fn resolve_attribute_macro( 847 fn resolve_derive_macro(
848 &self, 848 &self,
849 directive: &DeriveDirective, 849 directive: &DeriveDirective,
850 path: &ModPath, 850 path: &ModPath,
@@ -1118,7 +1118,8 @@ impl ModCollector<'_, '_> {
1118 ModItem::Function(id) => { 1118 ModItem::Function(id) => {
1119 let func = &self.item_tree[id]; 1119 let func = &self.item_tree[id];
1120 1120
1121 self.collect_proc_macro_def(&func.name, &attrs); 1121 let ast_id = InFile::new(self.file_id, func.ast_id);
1122 self.collect_proc_macro_def(&func.name, ast_id, &attrs);
1122 1123
1123 def = Some(DefData { 1124 def = Some(DefData {
1124 id: FunctionLoc { 1125 id: FunctionLoc {
@@ -1293,29 +1294,37 @@ impl ModCollector<'_, '_> {
1293 let db = self.def_collector.db; 1294 let db = self.def_collector.db;
1294 match self.mod_dir.resolve_declaration(db, self.file_id, &module.name, path_attr) { 1295 match self.mod_dir.resolve_declaration(db, self.file_id, &module.name, path_attr) {
1295 Ok((file_id, is_mod_rs, mod_dir)) => { 1296 Ok((file_id, is_mod_rs, mod_dir)) => {
1296 let module_id = self.push_child_module(
1297 module.name.clone(),
1298 ast_id,
1299 Some((file_id, is_mod_rs)),
1300 &self.item_tree[module.visibility],
1301 );
1302 let item_tree = db.file_item_tree(file_id.into()); 1297 let item_tree = db.file_item_tree(file_id.into());
1303 ModCollector { 1298 if item_tree
1304 def_collector: &mut *self.def_collector, 1299 .top_level_attrs(db, self.def_collector.def_map.krate)
1305 macro_depth: self.macro_depth, 1300 .cfg()
1306 module_id, 1301 .map_or(true, |cfg| {
1307 file_id: file_id.into(), 1302 self.def_collector.cfg_options.check(&cfg) != Some(false)
1308 item_tree: &item_tree, 1303 })
1309 mod_dir,
1310 }
1311 .collect(item_tree.top_level_items());
1312 if is_macro_use
1313 || item_tree
1314 .top_level_attrs(db, self.def_collector.def_map.krate)
1315 .by_key("macro_use")
1316 .exists()
1317 { 1304 {
1318 self.import_all_legacy_macros(module_id); 1305 let module_id = self.push_child_module(
1306 module.name.clone(),
1307 ast_id,
1308 Some((file_id, is_mod_rs)),
1309 &self.item_tree[module.visibility],
1310 );
1311 ModCollector {
1312 def_collector: &mut *self.def_collector,
1313 macro_depth: self.macro_depth,
1314 module_id,
1315 file_id: file_id.into(),
1316 item_tree: &item_tree,
1317 mod_dir,
1318 }
1319 .collect(item_tree.top_level_items());
1320 if is_macro_use
1321 || item_tree
1322 .top_level_attrs(db, self.def_collector.def_map.krate)
1323 .by_key("macro_use")
1324 .exists()
1325 {
1326 self.import_all_legacy_macros(module_id);
1327 }
1319 } 1328 }
1320 } 1329 }
1321 Err(candidate) => { 1330 Err(candidate) => {
@@ -1385,28 +1394,11 @@ impl ModCollector<'_, '_> {
1385 } 1394 }
1386 1395
1387 /// If `attrs` registers a procedural macro, collects its definition. 1396 /// If `attrs` registers a procedural macro, collects its definition.
1388 fn collect_proc_macro_def(&mut self, func_name: &Name, attrs: &Attrs) { 1397 fn collect_proc_macro_def(&mut self, func_name: &Name, ast_id: AstId<ast::Fn>, attrs: &Attrs) {
1389 // FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere 1398 // FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere
1390 // FIXME: distinguish the type of macro 1399 if let Some(proc_macro) = attrs.parse_proc_macro_decl(func_name) {
1391 let macro_name = if attrs.by_key("proc_macro").exists() 1400 self.def_collector.export_proc_macro(proc_macro, ast_id);
1392 || attrs.by_key("proc_macro_attribute").exists() 1401 }
1393 {
1394 func_name.clone()
1395 } else {
1396 let derive = attrs.by_key("proc_macro_derive");
1397 if let Some(arg) = derive.tt_values().next() {
1398 if let [TokenTree::Leaf(Leaf::Ident(trait_name)), ..] = &*arg.token_trees {
1399 trait_name.as_name()
1400 } else {
1401 log::trace!("malformed `#[proc_macro_derive]`: {}", arg);
1402 return;
1403 }
1404 } else {
1405 return;
1406 }
1407 };
1408
1409 self.def_collector.resolve_proc_macro(&macro_name);
1410 } 1402 }
1411 1403
1412 fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) { 1404 fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) {
@@ -1445,9 +1437,8 @@ impl ModCollector<'_, '_> {
1445 1437
1446 // Case 2: normal `macro_rules!` macro 1438 // Case 2: normal `macro_rules!` macro
1447 let macro_id = MacroDefId { 1439 let macro_id = MacroDefId {
1448 ast_id: Some(ast_id),
1449 krate: self.def_collector.def_map.krate, 1440 krate: self.def_collector.def_map.krate,
1450 kind: MacroDefKind::Declarative, 1441 kind: MacroDefKind::Declarative(ast_id),
1451 local_inner: is_local_inner, 1442 local_inner: is_local_inner,
1452 }; 1443 };
1453 self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, is_export); 1444 self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, is_export);
@@ -1476,12 +1467,13 @@ impl ModCollector<'_, '_> {
1476 }, 1467 },
1477 ) { 1468 ) {
1478 Ok(Ok(macro_call_id)) => { 1469 Ok(Ok(macro_call_id)) => {
1479 self.def_collector.unexpanded_macros.push(MacroDirective { 1470 // Legacy macros need to be expanded immediately, so that any macros they produce
1480 module_id: self.module_id, 1471 // are in scope.
1481 ast_id, 1472 self.def_collector.collect_macro_expansion(
1482 legacy: Some(macro_call_id), 1473 self.module_id,
1483 depth: self.macro_depth + 1, 1474 macro_call_id,
1484 }); 1475 self.macro_depth + 1,
1476 );
1485 1477
1486 return; 1478 return;
1487 } 1479 }
diff --git a/crates/hir_def/src/nameres/mod_resolution.rs b/crates/hir_def/src/nameres/mod_resolution.rs
index d5de9899c..d9cec0e27 100644
--- a/crates/hir_def/src/nameres/mod_resolution.rs
+++ b/crates/hir_def/src/nameres/mod_resolution.rs
@@ -62,7 +62,7 @@ impl ModDir {
62 name: &Name, 62 name: &Name,
63 attr_path: Option<&SmolStr>, 63 attr_path: Option<&SmolStr>,
64 ) -> Result<(FileId, bool, ModDir), String> { 64 ) -> Result<(FileId, bool, ModDir), String> {
65 let file_id = file_id.original_file(db.upcast()); 65 let orig_file_id = file_id.original_file(db.upcast());
66 66
67 let mut candidate_files = Vec::new(); 67 let mut candidate_files = Vec::new();
68 match attr_path { 68 match attr_path {
@@ -70,13 +70,18 @@ impl ModDir {
70 candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner)) 70 candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner))
71 } 71 }
72 None => { 72 None => {
73 candidate_files.push(format!("{}{}.rs", self.dir_path.0, name)); 73 if file_id.is_include_macro(db.upcast()) {
74 candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name)); 74 candidate_files.push(format!("{}.rs", name));
75 candidate_files.push(format!("{}/mod.rs", name));
76 } else {
77 candidate_files.push(format!("{}{}.rs", self.dir_path.0, name));
78 candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name));
79 }
75 } 80 }
76 }; 81 };
77 82
78 for candidate in candidate_files.iter() { 83 for candidate in candidate_files.iter() {
79 let path = AnchoredPath { anchor: file_id, path: candidate.as_str() }; 84 let path = AnchoredPath { anchor: orig_file_id, path: candidate.as_str() };
80 if let Some(file_id) = db.resolve_path(path) { 85 if let Some(file_id) = db.resolve_path(path) {
81 let is_mod_rs = candidate.ends_with("/mod.rs"); 86 let is_mod_rs = candidate.ends_with("/mod.rs");
82 87
diff --git a/crates/hir_def/src/nameres/proc_macro.rs b/crates/hir_def/src/nameres/proc_macro.rs
new file mode 100644
index 000000000..156598f19
--- /dev/null
+++ b/crates/hir_def/src/nameres/proc_macro.rs
@@ -0,0 +1,71 @@
1//! Nameres-specific procedural macro data and helpers.
2
3use hir_expand::name::{AsName, Name};
4use tt::{Leaf, TokenTree};
5
6use crate::attr::Attrs;
7
8#[derive(Debug, PartialEq, Eq)]
9pub(super) struct ProcMacroDef {
10 pub(super) name: Name,
11 pub(super) kind: ProcMacroKind,
12}
13
14#[derive(Debug, PartialEq, Eq)]
15pub(super) enum ProcMacroKind {
16 CustomDerive { helpers: Box<[Name]> },
17 FnLike,
18 Attr,
19}
20
21impl Attrs {
22 #[rustfmt::skip]
23 pub(super) fn parse_proc_macro_decl(&self, func_name: &Name) -> Option<ProcMacroDef> {
24 if self.by_key("proc_macro").exists() {
25 Some(ProcMacroDef { name: func_name.clone(), kind: ProcMacroKind::FnLike })
26 } else if self.by_key("proc_macro_attribute").exists() {
27 Some(ProcMacroDef { name: func_name.clone(), kind: ProcMacroKind::Attr })
28 } else if self.by_key("proc_macro_derive").exists() {
29 let derive = self.by_key("proc_macro_derive").tt_values().next().unwrap();
30
31 match &*derive.token_trees {
32 // `#[proc_macro_derive(Trait)]`
33 [TokenTree::Leaf(Leaf::Ident(trait_name))] => Some(ProcMacroDef {
34 name: trait_name.as_name(),
35 kind: ProcMacroKind::CustomDerive { helpers: Box::new([]) },
36 }),
37
38 // `#[proc_macro_derive(Trait, attibutes(helper1, helper2, ...))]`
39 [
40 TokenTree::Leaf(Leaf::Ident(trait_name)),
41 TokenTree::Leaf(Leaf::Punct(comma)),
42 TokenTree::Leaf(Leaf::Ident(attributes)),
43 TokenTree::Subtree(helpers)
44 ] if comma.char == ',' && attributes.text == "attributes" =>
45 {
46 let helpers = helpers.token_trees.iter()
47 .filter(|tt| !matches!(tt, TokenTree::Leaf(Leaf::Punct(comma)) if comma.char == ','))
48 .map(|tt| {
49 match tt {
50 TokenTree::Leaf(Leaf::Ident(helper)) => Some(helper.as_name()),
51 _ => None
52 }
53 })
54 .collect::<Option<Box<[_]>>>()?;
55
56 Some(ProcMacroDef {
57 name: trait_name.as_name(),
58 kind: ProcMacroKind::CustomDerive { helpers },
59 })
60 }
61
62 _ => {
63 log::trace!("malformed `#[proc_macro_derive]`: {}", derive);
64 None
65 }
66 }
67 } else {
68 None
69 }
70 }
71}
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs
index f65a655bf..6d3cb8d7a 100644
--- a/crates/hir_def/src/nameres/tests/macros.rs
+++ b/crates/hir_def/src/nameres/tests/macros.rs
@@ -1,4 +1,5 @@
1use super::*; 1use super::*;
2use crate::nameres::proc_macro::{ProcMacroDef, ProcMacroKind};
2 3
3#[test] 4#[test]
4fn macro_rules_are_globally_visible() { 5fn macro_rules_are_globally_visible() {
@@ -712,6 +713,27 @@ b! { static = #[] ();}
712} 713}
713 714
714#[test] 715#[test]
716fn macros_defining_macros() {
717 check(
718 r#"
719macro_rules! item {
720 ($item:item) => { $item }
721}
722
723item! {
724 macro_rules! indirect_macro { () => { struct S {} } }
725}
726
727indirect_macro!();
728 "#,
729 expect![[r#"
730 crate
731 S: t
732 "#]],
733 );
734}
735
736#[test]
715fn resolves_proc_macros() { 737fn resolves_proc_macros() {
716 check( 738 check(
717 r" 739 r"
@@ -790,3 +812,28 @@ fn proc_macro_censoring() {
790 "#]], 812 "#]],
791 ); 813 );
792} 814}
815
816#[test]
817fn collects_derive_helpers() {
818 let def_map = compute_crate_def_map(
819 r"
820 struct TokenStream;
821
822 #[proc_macro_derive(AnotherTrait, attributes(helper_attr))]
823 pub fn derive_macro_2(_item: TokenStream) -> TokenStream {
824 TokenStream
825 }
826 ",
827 );
828
829 assert_eq!(def_map.exported_proc_macros.len(), 1);
830 match def_map.exported_proc_macros.values().next() {
831 Some(ProcMacroDef { kind: ProcMacroKind::CustomDerive { helpers }, .. }) => {
832 match &**helpers {
833 [attr] => assert_eq!(attr.to_string(), "helper_attr"),
834 _ => unreachable!(),
835 }
836 }
837 _ => unreachable!(),
838 }
839}
diff --git a/crates/hir_def/src/nameres/tests/mod_resolution.rs b/crates/hir_def/src/nameres/tests/mod_resolution.rs
index dfbbad1f9..16a2cd27a 100644
--- a/crates/hir_def/src/nameres/tests/mod_resolution.rs
+++ b/crates/hir_def/src/nameres/tests/mod_resolution.rs
@@ -819,3 +819,22 @@ pub mod hash { pub trait Hash {} }
819 "#]], 819 "#]],
820 ); 820 );
821} 821}
822
823#[test]
824fn cfg_in_module_file() {
825 // Inner `#![cfg]` in a module file makes the whole module disappear.
826 check(
827 r#"
828//- /main.rs
829mod module;
830
831//- /module.rs
832#![cfg(NEVER)]
833
834struct AlsoShoulntAppear;
835 "#,
836 expect![[r#"
837 crate
838 "#]],
839 )
840}
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index 42736171e..04ea9c5d7 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -12,7 +12,7 @@ use crate::{
12 body::scope::{ExprScopes, ScopeId}, 12 body::scope::{ExprScopes, ScopeId},
13 builtin_type::BuiltinType, 13 builtin_type::BuiltinType,
14 db::DefDatabase, 14 db::DefDatabase,
15 expr::{ExprId, PatId}, 15 expr::{ExprId, LabelId, PatId},
16 generics::GenericParams, 16 generics::GenericParams,
17 item_scope::{BuiltinShadowMode, BUILTIN_SCOPE}, 17 item_scope::{BuiltinShadowMode, BUILTIN_SCOPE},
18 nameres::DefMap, 18 nameres::DefMap,
@@ -409,6 +409,7 @@ pub enum ScopeDef {
409 AdtSelfType(AdtId), 409 AdtSelfType(AdtId),
410 GenericParam(GenericParamId), 410 GenericParam(GenericParamId),
411 Local(PatId), 411 Local(PatId),
412 Label(LabelId),
412} 413}
413 414
414impl Scope { 415impl Scope {
@@ -470,6 +471,9 @@ impl Scope {
470 f(name![Self], ScopeDef::AdtSelfType(*i)); 471 f(name![Self], ScopeDef::AdtSelfType(*i));
471 } 472 }
472 Scope::ExprScope(scope) => { 473 Scope::ExprScope(scope) => {
474 if let Some((label, name)) = scope.expr_scopes.label(scope.scope_id) {
475 f(name, ScopeDef::Label(label))
476 }
473 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { 477 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| {
474 f(e.name().clone(), ScopeDef::Local(e.pat())); 478 f(e.name().clone(), ScopeDef::Local(e.pat()));
475 }); 479 });
diff --git a/crates/hir_expand/src/builtin_derive.rs b/crates/hir_expand/src/builtin_derive.rs
index 5e908b223..6ece4b289 100644
--- a/crates/hir_expand/src/builtin_derive.rs
+++ b/crates/hir_expand/src/builtin_derive.rs
@@ -61,8 +61,7 @@ pub fn find_builtin_derive(
61 let expander = BuiltinDeriveExpander::find_by_name(ident)?; 61 let expander = BuiltinDeriveExpander::find_by_name(ident)?;
62 Some(MacroDefId { 62 Some(MacroDefId {
63 krate, 63 krate,
64 ast_id: Some(ast_id), 64 kind: MacroDefKind::BuiltInDerive(expander, ast_id),
65 kind: MacroDefKind::BuiltInDerive(expander),
66 local_inner: false, 65 local_inner: false,
67 }) 66 })
68} 67}
@@ -268,14 +267,13 @@ fn partial_ord_expand(
268mod tests { 267mod tests {
269 use base_db::{fixture::WithFixture, CrateId, SourceDatabase}; 268 use base_db::{fixture::WithFixture, CrateId, SourceDatabase};
270 use expect_test::{expect, Expect}; 269 use expect_test::{expect, Expect};
271 use name::{known, Name}; 270 use name::AsName;
272 271
273 use crate::{test_db::TestDB, AstId, MacroCallId, MacroCallKind, MacroCallLoc}; 272 use crate::{test_db::TestDB, AstId, MacroCallId, MacroCallKind, MacroCallLoc};
274 273
275 use super::*; 274 use super::*;
276 275
277 fn expand_builtin_derive(ra_fixture: &str, name: Name) -> String { 276 fn expand_builtin_derive(ra_fixture: &str) -> String {
278 let expander = BuiltinDeriveExpander::find_by_name(&name).unwrap();
279 let fixture = format!( 277 let fixture = format!(
280 r#"//- /main.rs crate:main deps:core 278 r#"//- /main.rs crate:main deps:core
281$0 279$0
@@ -288,23 +286,38 @@ $0
288 286
289 let (db, file_pos) = TestDB::with_position(&fixture); 287 let (db, file_pos) = TestDB::with_position(&fixture);
290 let file_id = file_pos.file_id; 288 let file_id = file_pos.file_id;
289 let ast_id_map = db.ast_id_map(file_id.into());
291 let parsed = db.parse(file_id); 290 let parsed = db.parse(file_id);
292 let items: Vec<_> = 291 let macros: Vec<_> =
293 parsed.syntax_node().descendants().filter_map(ast::Item::cast).collect(); 292 parsed.syntax_node().descendants().filter_map(ast::Macro::cast).collect();
293 let items: Vec<_> = parsed
294 .syntax_node()
295 .descendants()
296 .filter(|node| !ast::Macro::can_cast(node.kind()))
297 .filter_map(ast::Item::cast)
298 .collect();
299
300 assert_eq!(macros.len(), 1, "test must contain exactly 1 macro definition");
301 assert_eq!(items.len(), 1, "test must contain exactly 1 item");
302
303 let macro_ast_id = AstId::new(file_id.into(), ast_id_map.ast_id(&macros[0]));
304 let name = match &macros[0] {
305 ast::Macro::MacroRules(rules) => rules.name().unwrap().as_name(),
306 ast::Macro::MacroDef(def) => def.name().unwrap().as_name(),
307 };
294 308
295 let ast_id_map = db.ast_id_map(file_id.into()); 309 let expander = BuiltinDeriveExpander::find_by_name(&name).unwrap();
296 310
297 let attr_id = AstId::new(file_id.into(), ast_id_map.ast_id(&items[0])); 311 let attr_id = AstId::new(file_id.into(), ast_id_map.ast_id(&items[0]));
298 312
299 let loc = MacroCallLoc { 313 let loc = MacroCallLoc {
300 def: MacroDefId { 314 def: MacroDefId {
301 krate: CrateId(0), 315 krate: CrateId(0),
302 ast_id: None, 316 kind: MacroDefKind::BuiltInDerive(expander, macro_ast_id),
303 kind: MacroDefKind::BuiltInDerive(expander),
304 local_inner: false, 317 local_inner: false,
305 }, 318 },
306 krate: CrateId(0), 319 krate: CrateId(0),
307 kind: MacroCallKind::Attr(attr_id, name.to_string()), 320 kind: MacroCallKind::Derive(attr_id, name.to_string()),
308 }; 321 };
309 322
310 let id: MacroCallId = db.intern_macro(loc).into(); 323 let id: MacroCallId = db.intern_macro(loc).into();
@@ -315,8 +328,8 @@ $0
315 parsed.text().to_string() 328 parsed.text().to_string()
316 } 329 }
317 330
318 fn check_derive(ra_fixture: &str, name: Name, expected: Expect) { 331 fn check_derive(ra_fixture: &str, expected: Expect) {
319 let expanded = expand_builtin_derive(ra_fixture, name); 332 let expanded = expand_builtin_derive(ra_fixture);
320 expected.assert_eq(&expanded); 333 expected.assert_eq(&expanded);
321 } 334 }
322 335
@@ -324,10 +337,10 @@ $0
324 fn test_copy_expand_simple() { 337 fn test_copy_expand_simple() {
325 check_derive( 338 check_derive(
326 r#" 339 r#"
340 macro Copy {}
327 #[derive(Copy)] 341 #[derive(Copy)]
328 struct Foo; 342 struct Foo;
329 "#, 343 "#,
330 known::Copy,
331 expect![["impl< >core::marker::CopyforFoo< >{}"]], 344 expect![["impl< >core::marker::CopyforFoo< >{}"]],
332 ); 345 );
333 } 346 }
@@ -336,10 +349,10 @@ $0
336 fn test_copy_expand_with_type_params() { 349 fn test_copy_expand_with_type_params() {
337 check_derive( 350 check_derive(
338 r#" 351 r#"
352 macro Copy {}
339 #[derive(Copy)] 353 #[derive(Copy)]
340 struct Foo<A, B>; 354 struct Foo<A, B>;
341 "#, 355 "#,
342 known::Copy,
343 expect![["impl<T0:core::marker::Copy,T1:core::marker::Copy>core::marker::CopyforFoo<T0,T1>{}"]], 356 expect![["impl<T0:core::marker::Copy,T1:core::marker::Copy>core::marker::CopyforFoo<T0,T1>{}"]],
344 ); 357 );
345 } 358 }
@@ -348,10 +361,10 @@ $0
348 fn test_copy_expand_with_lifetimes() { 361 fn test_copy_expand_with_lifetimes() {
349 check_derive( 362 check_derive(
350 r#" 363 r#"
364 macro Copy {}
351 #[derive(Copy)] 365 #[derive(Copy)]
352 struct Foo<A, B, 'a, 'b>; 366 struct Foo<A, B, 'a, 'b>;
353 "#, 367 "#,
354 known::Copy,
355 // We currently just ignore lifetimes 368 // We currently just ignore lifetimes
356 expect![["impl<T0:core::marker::Copy,T1:core::marker::Copy>core::marker::CopyforFoo<T0,T1>{}"]], 369 expect![["impl<T0:core::marker::Copy,T1:core::marker::Copy>core::marker::CopyforFoo<T0,T1>{}"]],
357 ); 370 );
@@ -361,10 +374,10 @@ $0
361 fn test_clone_expand() { 374 fn test_clone_expand() {
362 check_derive( 375 check_derive(
363 r#" 376 r#"
377 macro Clone {}
364 #[derive(Clone)] 378 #[derive(Clone)]
365 struct Foo<A, B>; 379 struct Foo<A, B>;
366 "#, 380 "#,
367 known::Clone,
368 expect![["impl<T0:core::clone::Clone,T1:core::clone::Clone>core::clone::CloneforFoo<T0,T1>{}"]], 381 expect![["impl<T0:core::clone::Clone,T1:core::clone::Clone>core::clone::CloneforFoo<T0,T1>{}"]],
369 ); 382 );
370 } 383 }
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index fce09a9e7..4d52904b9 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -43,7 +43,7 @@ macro_rules! register_builtin {
43 db: &dyn AstDatabase, 43 db: &dyn AstDatabase,
44 arg_id: EagerMacroId, 44 arg_id: EagerMacroId,
45 tt: &tt::Subtree, 45 tt: &tt::Subtree,
46 ) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 46 ) -> ExpandResult<Option<ExpandedEager>> {
47 let expander = match *self { 47 let expander = match *self {
48 $( EagerExpander::$e_kind => $e_expand, )* 48 $( EagerExpander::$e_kind => $e_expand, )*
49 }; 49 };
@@ -61,6 +61,20 @@ macro_rules! register_builtin {
61 }; 61 };
62} 62}
63 63
64#[derive(Debug)]
65pub struct ExpandedEager {
66 pub(crate) subtree: tt::Subtree,
67 pub(crate) fragment: FragmentKind,
68 /// The included file ID of the include macro.
69 pub(crate) included_file: Option<FileId>,
70}
71
72impl ExpandedEager {
73 fn new(subtree: tt::Subtree, fragment: FragmentKind) -> Self {
74 ExpandedEager { subtree, fragment, included_file: None }
75 }
76}
77
64pub fn find_builtin_macro( 78pub fn find_builtin_macro(
65 ident: &name::Name, 79 ident: &name::Name,
66 krate: CrateId, 80 krate: CrateId,
@@ -71,14 +85,12 @@ pub fn find_builtin_macro(
71 match kind { 85 match kind {
72 Either::Left(kind) => Some(MacroDefId { 86 Either::Left(kind) => Some(MacroDefId {
73 krate, 87 krate,
74 ast_id: Some(ast_id), 88 kind: MacroDefKind::BuiltIn(kind, ast_id),
75 kind: MacroDefKind::BuiltIn(kind),
76 local_inner: false, 89 local_inner: false,
77 }), 90 }),
78 Either::Right(kind) => Some(MacroDefId { 91 Either::Right(kind) => Some(MacroDefId {
79 krate, 92 krate,
80 ast_id: Some(ast_id), 93 kind: MacroDefKind::BuiltInEager(kind, ast_id),
81 kind: MacroDefKind::BuiltInEager(kind),
82 local_inner: false, 94 local_inner: false,
83 }), 95 }),
84 } 96 }
@@ -282,7 +294,7 @@ fn compile_error_expand(
282 _db: &dyn AstDatabase, 294 _db: &dyn AstDatabase,
283 _id: EagerMacroId, 295 _id: EagerMacroId,
284 tt: &tt::Subtree, 296 tt: &tt::Subtree,
285) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 297) -> ExpandResult<Option<ExpandedEager>> {
286 let err = match &*tt.token_trees { 298 let err = match &*tt.token_trees {
287 [tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => { 299 [tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => {
288 let text = it.text.as_str(); 300 let text = it.text.as_str();
@@ -296,14 +308,14 @@ fn compile_error_expand(
296 _ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()), 308 _ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()),
297 }; 309 };
298 310
299 ExpandResult { value: Some((quote! {}, FragmentKind::Items)), err: Some(err) } 311 ExpandResult { value: Some(ExpandedEager::new(quote! {}, FragmentKind::Items)), err: Some(err) }
300} 312}
301 313
302fn concat_expand( 314fn concat_expand(
303 _db: &dyn AstDatabase, 315 _db: &dyn AstDatabase,
304 _arg_id: EagerMacroId, 316 _arg_id: EagerMacroId,
305 tt: &tt::Subtree, 317 tt: &tt::Subtree,
306) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 318) -> ExpandResult<Option<ExpandedEager>> {
307 let mut err = None; 319 let mut err = None;
308 let mut text = String::new(); 320 let mut text = String::new();
309 for (i, t) in tt.token_trees.iter().enumerate() { 321 for (i, t) in tt.token_trees.iter().enumerate() {
@@ -327,7 +339,7 @@ fn concat_expand(
327 } 339 }
328 } 340 }
329 } 341 }
330 ExpandResult { value: Some((quote!(#text), FragmentKind::Expr)), err } 342 ExpandResult { value: Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)), err }
331} 343}
332 344
333fn relative_file( 345fn relative_file(
@@ -363,21 +375,27 @@ fn include_expand(
363 db: &dyn AstDatabase, 375 db: &dyn AstDatabase,
364 arg_id: EagerMacroId, 376 arg_id: EagerMacroId,
365 tt: &tt::Subtree, 377 tt: &tt::Subtree,
366) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 378) -> ExpandResult<Option<ExpandedEager>> {
367 let res = (|| { 379 let res = (|| {
368 let path = parse_string(tt)?; 380 let path = parse_string(tt)?;
369 let file_id = relative_file(db, arg_id.into(), &path, false)?; 381 let file_id = relative_file(db, arg_id.into(), &path, false)?;
370 382
371 Ok(parse_to_token_tree(&db.file_text(file_id)) 383 let subtree = parse_to_token_tree(&db.file_text(file_id))
372 .ok_or_else(|| mbe::ExpandError::ConversionError)? 384 .ok_or_else(|| mbe::ExpandError::ConversionError)?
373 .0) 385 .0;
386 Ok((subtree, file_id))
374 })(); 387 })();
375 388
376 match res { 389 match res {
377 Ok(res) => { 390 Ok((subtree, file_id)) => {
378 // FIXME: 391 // FIXME:
379 // Handle include as expression 392 // Handle include as expression
380 ExpandResult::ok(Some((res, FragmentKind::Items))) 393
394 ExpandResult::ok(Some(ExpandedEager {
395 subtree,
396 fragment: FragmentKind::Items,
397 included_file: Some(file_id),
398 }))
381 } 399 }
382 Err(e) => ExpandResult::only_err(e), 400 Err(e) => ExpandResult::only_err(e),
383 } 401 }
@@ -387,7 +405,7 @@ fn include_bytes_expand(
387 _db: &dyn AstDatabase, 405 _db: &dyn AstDatabase,
388 _arg_id: EagerMacroId, 406 _arg_id: EagerMacroId,
389 tt: &tt::Subtree, 407 tt: &tt::Subtree,
390) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 408) -> ExpandResult<Option<ExpandedEager>> {
391 if let Err(e) = parse_string(tt) { 409 if let Err(e) = parse_string(tt) {
392 return ExpandResult::only_err(e); 410 return ExpandResult::only_err(e);
393 } 411 }
@@ -400,14 +418,14 @@ fn include_bytes_expand(
400 id: tt::TokenId::unspecified(), 418 id: tt::TokenId::unspecified(),
401 }))], 419 }))],
402 }; 420 };
403 ExpandResult::ok(Some((res, FragmentKind::Expr))) 421 ExpandResult::ok(Some(ExpandedEager::new(res, FragmentKind::Expr)))
404} 422}
405 423
406fn include_str_expand( 424fn include_str_expand(
407 db: &dyn AstDatabase, 425 db: &dyn AstDatabase,
408 arg_id: EagerMacroId, 426 arg_id: EagerMacroId,
409 tt: &tt::Subtree, 427 tt: &tt::Subtree,
410) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 428) -> ExpandResult<Option<ExpandedEager>> {
411 let path = match parse_string(tt) { 429 let path = match parse_string(tt) {
412 Ok(it) => it, 430 Ok(it) => it,
413 Err(e) => return ExpandResult::only_err(e), 431 Err(e) => return ExpandResult::only_err(e),
@@ -420,14 +438,14 @@ fn include_str_expand(
420 let file_id = match relative_file(db, arg_id.into(), &path, true) { 438 let file_id = match relative_file(db, arg_id.into(), &path, true) {
421 Ok(file_id) => file_id, 439 Ok(file_id) => file_id,
422 Err(_) => { 440 Err(_) => {
423 return ExpandResult::ok(Some((quote!(""), FragmentKind::Expr))); 441 return ExpandResult::ok(Some(ExpandedEager::new(quote!(""), FragmentKind::Expr)));
424 } 442 }
425 }; 443 };
426 444
427 let text = db.file_text(file_id); 445 let text = db.file_text(file_id);
428 let text = &*text; 446 let text = &*text;
429 447
430 ExpandResult::ok(Some((quote!(#text), FragmentKind::Expr))) 448 ExpandResult::ok(Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)))
431} 449}
432 450
433fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> { 451fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> {
@@ -439,7 +457,7 @@ fn env_expand(
439 db: &dyn AstDatabase, 457 db: &dyn AstDatabase,
440 arg_id: EagerMacroId, 458 arg_id: EagerMacroId,
441 tt: &tt::Subtree, 459 tt: &tt::Subtree,
442) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 460) -> ExpandResult<Option<ExpandedEager>> {
443 let key = match parse_string(tt) { 461 let key = match parse_string(tt) {
444 Ok(it) => it, 462 Ok(it) => it,
445 Err(e) => return ExpandResult::only_err(e), 463 Err(e) => return ExpandResult::only_err(e),
@@ -463,14 +481,14 @@ fn env_expand(
463 }); 481 });
464 let expanded = quote! { #s }; 482 let expanded = quote! { #s };
465 483
466 ExpandResult { value: Some((expanded, FragmentKind::Expr)), err } 484 ExpandResult { value: Some(ExpandedEager::new(expanded, FragmentKind::Expr)), err }
467} 485}
468 486
469fn option_env_expand( 487fn option_env_expand(
470 db: &dyn AstDatabase, 488 db: &dyn AstDatabase,
471 arg_id: EagerMacroId, 489 arg_id: EagerMacroId,
472 tt: &tt::Subtree, 490 tt: &tt::Subtree,
473) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 491) -> ExpandResult<Option<ExpandedEager>> {
474 let key = match parse_string(tt) { 492 let key = match parse_string(tt) {
475 Ok(it) => it, 493 Ok(it) => it,
476 Err(e) => return ExpandResult::only_err(e), 494 Err(e) => return ExpandResult::only_err(e),
@@ -481,7 +499,7 @@ fn option_env_expand(
481 Some(s) => quote! { std::option::Some(#s) }, 499 Some(s) => quote! { std::option::Some(#s) },
482 }; 500 };
483 501
484 ExpandResult::ok(Some((expanded, FragmentKind::Expr))) 502 ExpandResult::ok(Some(ExpandedEager::new(expanded, FragmentKind::Expr)))
485} 503}
486 504
487#[cfg(test)] 505#[cfg(test)]
@@ -512,6 +530,7 @@ mod tests {
512 let macro_call = macro_calls.pop().unwrap(); 530 let macro_call = macro_calls.pop().unwrap();
513 531
514 let expander = find_by_name(&macro_rules.name().unwrap().as_name()).unwrap(); 532 let expander = find_by_name(&macro_rules.name().unwrap().as_name()).unwrap();
533 let ast_id = AstId::new(file_id.into(), ast_id_map.ast_id(&macro_rules));
515 534
516 let krate = CrateId(0); 535 let krate = CrateId(0);
517 let file_id = match expander { 536 let file_id = match expander {
@@ -519,8 +538,7 @@ mod tests {
519 // the first one should be a macro_rules 538 // the first one should be a macro_rules
520 let def = MacroDefId { 539 let def = MacroDefId {
521 krate: CrateId(0), 540 krate: CrateId(0),
522 ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(&macro_rules))), 541 kind: MacroDefKind::BuiltIn(expander, ast_id),
523 kind: MacroDefKind::BuiltIn(expander),
524 local_inner: false, 542 local_inner: false,
525 }; 543 };
526 544
@@ -540,8 +558,7 @@ mod tests {
540 // the first one should be a macro_rules 558 // the first one should be a macro_rules
541 let def = MacroDefId { 559 let def = MacroDefId {
542 krate, 560 krate,
543 ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(&macro_rules))), 561 kind: MacroDefKind::BuiltInEager(expander, ast_id),
544 kind: MacroDefKind::BuiltInEager(expander),
545 local_inner: false, 562 local_inner: false,
546 }; 563 };
547 564
@@ -556,16 +573,18 @@ mod tests {
556 subtree: Arc::new(parsed_args.clone()), 573 subtree: Arc::new(parsed_args.clone()),
557 krate, 574 krate,
558 call: call_id, 575 call: call_id,
576 included_file: None,
559 } 577 }
560 }); 578 });
561 579
562 let (subtree, fragment) = expander.expand(&db, arg_id, &parsed_args).value.unwrap(); 580 let expanded = expander.expand(&db, arg_id, &parsed_args).value.unwrap();
563 let eager = EagerCallLoc { 581 let eager = EagerCallLoc {
564 def, 582 def,
565 fragment, 583 fragment: expanded.fragment,
566 subtree: Arc::new(subtree), 584 subtree: Arc::new(expanded.subtree),
567 krate, 585 krate,
568 call: call_id, 586 call: call_id,
587 included_file: expanded.included_file,
569 }; 588 };
570 589
571 let id: MacroCallId = db.intern_eager_expansion(eager).into(); 590 let id: MacroCallId = db.intern_eager_expansion(eager).into();
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs
index a3070f1f9..fc73e435b 100644
--- a/crates/hir_expand/src/db.rs
+++ b/crates/hir_expand/src/db.rs
@@ -130,8 +130,8 @@ fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> {
130 130
131fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { 131fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> {
132 match id.kind { 132 match id.kind {
133 MacroDefKind::Declarative => { 133 MacroDefKind::Declarative(ast_id) => {
134 let macro_rules = match id.ast_id?.to_node(db) { 134 let macro_rules = match ast_id.to_node(db) {
135 syntax::ast::Macro::MacroRules(mac) => mac, 135 syntax::ast::Macro::MacroRules(mac) => mac,
136 syntax::ast::Macro::MacroDef(_) => return None, 136 syntax::ast::Macro::MacroDef(_) => return None,
137 }; 137 };
@@ -150,14 +150,14 @@ fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander,
150 }; 150 };
151 Some(Arc::new((TokenExpander::MacroRules(rules), tmap))) 151 Some(Arc::new((TokenExpander::MacroRules(rules), tmap)))
152 } 152 }
153 MacroDefKind::BuiltIn(expander) => { 153 MacroDefKind::BuiltIn(expander, _) => {
154 Some(Arc::new((TokenExpander::Builtin(expander), mbe::TokenMap::default()))) 154 Some(Arc::new((TokenExpander::Builtin(expander), mbe::TokenMap::default())))
155 } 155 }
156 MacroDefKind::BuiltInDerive(expander) => { 156 MacroDefKind::BuiltInDerive(expander, _) => {
157 Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default()))) 157 Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default())))
158 } 158 }
159 MacroDefKind::BuiltInEager(_) => None, 159 MacroDefKind::BuiltInEager(..) => None,
160 MacroDefKind::ProcMacro(expander) => { 160 MacroDefKind::ProcMacro(expander, ..) => {
161 Some(Arc::new((TokenExpander::ProcMacro(expander), mbe::TokenMap::default()))) 161 Some(Arc::new((TokenExpander::ProcMacro(expander), mbe::TokenMap::default())))
162 } 162 }
163 } 163 }
@@ -173,7 +173,7 @@ fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option<GreenNode> {
173 }; 173 };
174 let loc = db.lookup_intern_macro(id); 174 let loc = db.lookup_intern_macro(id);
175 let arg = loc.kind.arg(db)?; 175 let arg = loc.kind.arg(db)?;
176 Some(arg.green().to_owned()) 176 Some(arg.green())
177} 177}
178 178
179fn macro_arg(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> { 179fn macro_arg(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> {
@@ -269,7 +269,7 @@ fn expand_proc_macro(
269 }; 269 };
270 270
271 let expander = match loc.def.kind { 271 let expander = match loc.def.kind {
272 MacroDefKind::ProcMacro(expander) => expander, 272 MacroDefKind::ProcMacro(expander, ..) => expander,
273 _ => unreachable!(), 273 _ => unreachable!(),
274 }; 274 };
275 275
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs
index dc618a9ee..9eedc8461 100644
--- a/crates/hir_expand/src/eager.rs
+++ b/crates/hir_expand/src/eager.rs
@@ -124,6 +124,7 @@ pub fn expand_eager_macro(
124 subtree: Arc::new(parsed_args.clone()), 124 subtree: Arc::new(parsed_args.clone()),
125 krate, 125 krate,
126 call: call_id, 126 call: call_id,
127 included_file: None,
127 } 128 }
128 }); 129 });
129 let arg_file_id: MacroCallId = arg_id.into(); 130 let arg_file_id: MacroCallId = arg_id.into();
@@ -140,12 +141,18 @@ pub fn expand_eager_macro(
140 let subtree = 141 let subtree =
141 diagnostic_sink.option(to_subtree(&result), || err("failed to parse macro result"))?; 142 diagnostic_sink.option(to_subtree(&result), || err("failed to parse macro result"))?;
142 143
143 if let MacroDefKind::BuiltInEager(eager) = def.kind { 144 if let MacroDefKind::BuiltInEager(eager, _) = def.kind {
144 let res = eager.expand(db, arg_id, &subtree); 145 let res = eager.expand(db, arg_id, &subtree);
145 146
146 let (subtree, fragment) = diagnostic_sink.expand_result_option(res)?; 147 let expanded = diagnostic_sink.expand_result_option(res)?;
147 let eager = 148 let eager = EagerCallLoc {
148 EagerCallLoc { def, fragment, subtree: Arc::new(subtree), krate, call: call_id }; 149 def,
150 fragment: expanded.fragment,
151 subtree: Arc::new(expanded.subtree),
152 krate,
153 call: call_id,
154 included_file: expanded.included_file,
155 };
149 156
150 Ok(db.intern_eager_expansion(eager)) 157 Ok(db.intern_eager_expansion(eager))
151 } else { 158 } else {
@@ -193,7 +200,7 @@ fn eager_macro_recur(
193 let def = diagnostic_sink 200 let def = diagnostic_sink
194 .option_with(|| macro_resolver(child.path()?), || err("failed to resolve macro"))?; 201 .option_with(|| macro_resolver(child.path()?), || err("failed to resolve macro"))?;
195 let insert = match def.kind { 202 let insert = match def.kind {
196 MacroDefKind::BuiltInEager(_) => { 203 MacroDefKind::BuiltInEager(..) => {
197 let id: MacroCallId = expand_eager_macro( 204 let id: MacroCallId = expand_eager_macro(
198 db, 205 db,
199 krate, 206 krate,
@@ -206,10 +213,10 @@ fn eager_macro_recur(
206 db.parse_or_expand(id.as_file()) 213 db.parse_or_expand(id.as_file())
207 .expect("successful macro expansion should be parseable") 214 .expect("successful macro expansion should be parseable")
208 } 215 }
209 MacroDefKind::Declarative 216 MacroDefKind::Declarative(_)
210 | MacroDefKind::BuiltIn(_) 217 | MacroDefKind::BuiltIn(..)
211 | MacroDefKind::BuiltInDerive(_) 218 | MacroDefKind::BuiltInDerive(..)
212 | MacroDefKind::ProcMacro(_) => { 219 | MacroDefKind::ProcMacro(..) => {
213 let res = lazy_expand(db, &def, curr.with_value(child.clone()), krate); 220 let res = lazy_expand(db, &def, curr.with_value(child.clone()), krate);
214 let val = diagnostic_sink.expand_result_option(res)?; 221 let val = diagnostic_sink.expand_result_option(res)?;
215 222
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs
index 87cad326d..0e0f7214a 100644
--- a/crates/hir_expand/src/hygiene.rs
+++ b/crates/hir_expand/src/hygiene.rs
@@ -145,7 +145,7 @@ fn make_hygiene_info(
145) -> Option<HygieneInfo> { 145) -> Option<HygieneInfo> {
146 let arg_tt = loc.kind.arg(db)?; 146 let arg_tt = loc.kind.arg(db)?;
147 147
148 let def_offset = loc.def.ast_id.and_then(|id| { 148 let def_offset = loc.def.ast_id().left().and_then(|id| {
149 let def_tt = match id.to_node(db) { 149 let def_tt = match id.to_node(db) {
150 ast::Macro::MacroRules(mac) => mac.token_tree()?.syntax().text_range().start(), 150 ast::Macro::MacroRules(mac) => mac.token_tree()?.syntax().text_range().start(),
151 ast::Macro::MacroDef(_) => return None, 151 ast::Macro::MacroDef(_) => return None,
@@ -176,13 +176,13 @@ impl HygieneFrame {
176 let loc = db.lookup_intern_macro(id); 176 let loc = db.lookup_intern_macro(id);
177 let info = make_hygiene_info(db, macro_file, &loc); 177 let info = make_hygiene_info(db, macro_file, &loc);
178 match loc.def.kind { 178 match loc.def.kind {
179 MacroDefKind::Declarative => { 179 MacroDefKind::Declarative(_) => {
180 (info, Some(loc.def.krate), loc.def.local_inner) 180 (info, Some(loc.def.krate), loc.def.local_inner)
181 } 181 }
182 MacroDefKind::BuiltIn(_) => (info, Some(loc.def.krate), false), 182 MacroDefKind::BuiltIn(..) => (info, Some(loc.def.krate), false),
183 MacroDefKind::BuiltInDerive(_) => (info, None, false), 183 MacroDefKind::BuiltInDerive(..) => (info, None, false),
184 MacroDefKind::BuiltInEager(_) => (info, None, false), 184 MacroDefKind::BuiltInEager(..) => (info, None, false),
185 MacroDefKind::ProcMacro(_) => (info, None, false), 185 MacroDefKind::ProcMacro(..) => (info, None, false),
186 } 186 }
187 } 187 }
188 }, 188 },
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index 7532d00b8..b8045fda9 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -15,6 +15,7 @@ pub mod proc_macro;
15pub mod quote; 15pub mod quote;
16pub mod eager; 16pub mod eager;
17 17
18use either::Either;
18pub use mbe::{ExpandError, ExpandResult}; 19pub use mbe::{ExpandError, ExpandResult};
19 20
20use std::hash::Hash; 21use std::hash::Hash;
@@ -83,7 +84,11 @@ impl HirFileId {
83 } 84 }
84 MacroCallId::EagerMacro(id) => { 85 MacroCallId::EagerMacro(id) => {
85 let loc = db.lookup_intern_eager_expansion(id); 86 let loc = db.lookup_intern_eager_expansion(id);
86 loc.call.file_id 87 if let Some(included_file) = loc.included_file {
88 return included_file;
89 } else {
90 loc.call.file_id
91 }
87 } 92 }
88 }; 93 };
89 file_id.original_file(db) 94 file_id.original_file(db)
@@ -143,7 +148,7 @@ impl HirFileId {
143 148
144 let arg_tt = loc.kind.arg(db)?; 149 let arg_tt = loc.kind.arg(db)?;
145 150
146 let def = loc.def.ast_id.and_then(|id| { 151 let def = loc.def.ast_id().left().and_then(|id| {
147 let def_tt = match id.to_node(db) { 152 let def_tt = match id.to_node(db) {
148 ast::Macro::MacroRules(mac) => mac.token_tree()?, 153 ast::Macro::MacroRules(mac) => mac.token_tree()?,
149 ast::Macro::MacroDef(_) => return None, 154 ast::Macro::MacroDef(_) => return None,
@@ -180,13 +185,28 @@ impl HirFileId {
180 }; 185 };
181 let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id); 186 let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id);
182 let item = match loc.def.kind { 187 let item = match loc.def.kind {
183 MacroDefKind::BuiltInDerive(_) => loc.kind.node(db), 188 MacroDefKind::BuiltInDerive(..) => loc.kind.node(db),
184 _ => return None, 189 _ => return None,
185 }; 190 };
186 Some(item.with_value(ast::Item::cast(item.value.clone())?)) 191 Some(item.with_value(ast::Item::cast(item.value.clone())?))
187 } 192 }
188 } 193 }
189 } 194 }
195
196 /// Return whether this file is an include macro
197 pub fn is_include_macro(&self, db: &dyn db::AstDatabase) -> bool {
198 match self.0 {
199 HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id {
200 MacroCallId::EagerMacro(id) => {
201 let loc = db.lookup_intern_eager_expansion(id);
202 return loc.included_file.is_some();
203 }
204 _ => {}
205 },
206 _ => {}
207 }
208 false
209 }
190} 210}
191 211
192#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 212#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -224,7 +244,6 @@ impl From<EagerMacroId> for MacroCallId {
224#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 244#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
225pub struct MacroDefId { 245pub struct MacroDefId {
226 pub krate: CrateId, 246 pub krate: CrateId,
227 pub ast_id: Option<AstId<ast::Macro>>,
228 pub kind: MacroDefKind, 247 pub kind: MacroDefKind,
229 248
230 pub local_inner: bool, 249 pub local_inner: bool,
@@ -239,16 +258,27 @@ impl MacroDefId {
239 ) -> LazyMacroId { 258 ) -> LazyMacroId {
240 db.intern_macro(MacroCallLoc { def: self, krate, kind }) 259 db.intern_macro(MacroCallLoc { def: self, krate, kind })
241 } 260 }
261
262 pub fn ast_id(&self) -> Either<AstId<ast::Macro>, AstId<ast::Fn>> {
263 let id = match &self.kind {
264 MacroDefKind::Declarative(id) => id,
265 MacroDefKind::BuiltIn(_, id) => id,
266 MacroDefKind::BuiltInDerive(_, id) => id,
267 MacroDefKind::BuiltInEager(_, id) => id,
268 MacroDefKind::ProcMacro(_, id) => return Either::Right(*id),
269 };
270 Either::Left(*id)
271 }
242} 272}
243 273
244#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 274#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
245pub enum MacroDefKind { 275pub enum MacroDefKind {
246 Declarative, 276 Declarative(AstId<ast::Macro>),
247 BuiltIn(BuiltinFnLikeExpander), 277 BuiltIn(BuiltinFnLikeExpander, AstId<ast::Macro>),
248 // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander 278 // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander
249 BuiltInDerive(BuiltinDeriveExpander), 279 BuiltInDerive(BuiltinDeriveExpander, AstId<ast::Macro>),
250 BuiltInEager(EagerExpander), 280 BuiltInEager(EagerExpander, AstId<ast::Macro>),
251 ProcMacro(ProcMacroExpander), 281 ProcMacro(ProcMacroExpander, AstId<ast::Fn>),
252} 282}
253 283
254#[derive(Debug, Clone, PartialEq, Eq, Hash)] 284#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -261,21 +291,21 @@ pub struct MacroCallLoc {
261#[derive(Debug, Clone, PartialEq, Eq, Hash)] 291#[derive(Debug, Clone, PartialEq, Eq, Hash)]
262pub enum MacroCallKind { 292pub enum MacroCallKind {
263 FnLike(AstId<ast::MacroCall>), 293 FnLike(AstId<ast::MacroCall>),
264 Attr(AstId<ast::Item>, String), 294 Derive(AstId<ast::Item>, String),
265} 295}
266 296
267impl MacroCallKind { 297impl MacroCallKind {
268 fn file_id(&self) -> HirFileId { 298 fn file_id(&self) -> HirFileId {
269 match self { 299 match self {
270 MacroCallKind::FnLike(ast_id) => ast_id.file_id, 300 MacroCallKind::FnLike(ast_id) => ast_id.file_id,
271 MacroCallKind::Attr(ast_id, _) => ast_id.file_id, 301 MacroCallKind::Derive(ast_id, _) => ast_id.file_id,
272 } 302 }
273 } 303 }
274 304
275 fn node(&self, db: &dyn db::AstDatabase) -> InFile<SyntaxNode> { 305 fn node(&self, db: &dyn db::AstDatabase) -> InFile<SyntaxNode> {
276 match self { 306 match self {
277 MacroCallKind::FnLike(ast_id) => ast_id.with_value(ast_id.to_node(db).syntax().clone()), 307 MacroCallKind::FnLike(ast_id) => ast_id.with_value(ast_id.to_node(db).syntax().clone()),
278 MacroCallKind::Attr(ast_id, _) => { 308 MacroCallKind::Derive(ast_id, _) => {
279 ast_id.with_value(ast_id.to_node(db).syntax().clone()) 309 ast_id.with_value(ast_id.to_node(db).syntax().clone())
280 } 310 }
281 } 311 }
@@ -286,7 +316,7 @@ impl MacroCallKind {
286 MacroCallKind::FnLike(ast_id) => { 316 MacroCallKind::FnLike(ast_id) => {
287 Some(ast_id.to_node(db).token_tree()?.syntax().clone()) 317 Some(ast_id.to_node(db).token_tree()?.syntax().clone())
288 } 318 }
289 MacroCallKind::Attr(ast_id, _) => Some(ast_id.to_node(db).syntax().clone()), 319 MacroCallKind::Derive(ast_id, _) => Some(ast_id.to_node(db).syntax().clone()),
290 } 320 }
291 } 321 }
292} 322}
@@ -304,6 +334,8 @@ pub struct EagerCallLoc {
304 pub(crate) subtree: Arc<tt::Subtree>, 334 pub(crate) subtree: Arc<tt::Subtree>,
305 pub(crate) krate: CrateId, 335 pub(crate) krate: CrateId,
306 pub(crate) call: AstId<ast::MacroCall>, 336 pub(crate) call: AstId<ast::MacroCall>,
337 // The included file ID of the include macro.
338 pub(crate) included_file: Option<FileId>,
307} 339}
308 340
309/// ExpansionInfo mainly describes how to map text range between src and expanded macro 341/// ExpansionInfo mainly describes how to map text range between src and expanded macro
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index 43de9edd6..0aeea48d5 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -48,9 +48,8 @@ impl Name {
48 48
49 /// Resolve a name from the text of token. 49 /// Resolve a name from the text of token.
50 fn resolve(raw_text: &str) -> Name { 50 fn resolve(raw_text: &str) -> Name {
51 let raw_start = "r#"; 51 if let Some(text) = raw_text.strip_prefix("r#") {
52 if raw_text.starts_with(raw_start) { 52 Name::new_text(SmolStr::new(text))
53 Name::new_text(SmolStr::new(&raw_text[raw_start.len()..]))
54 } else { 53 } else {
55 Name::new_text(raw_text.into()) 54 Name::new_text(raw_text.into())
56 } 55 }
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index bd2ff5d38..dc5fc759a 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -6,16 +6,18 @@
6use std::iter::successors; 6use std::iter::successors;
7 7
8use base_db::CrateId; 8use base_db::CrateId;
9use chalk_ir::cast::Cast;
9use hir_def::lang_item::LangItemTarget; 10use hir_def::lang_item::LangItemTarget;
10use hir_expand::name::name; 11use hir_expand::name::name;
11use log::{info, warn}; 12use log::{info, warn};
12 13
13use crate::{ 14use crate::{
14 db::HirDatabase, 15 db::HirDatabase,
15 to_assoc_type_id, 16 to_assoc_type_id, to_chalk_trait_id,
16 traits::{InEnvironment, Solution}, 17 traits::{InEnvironment, Solution},
17 utils::generics, 18 utils::generics,
18 BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substitution, TraitRef, Ty, TyKind, 19 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner,
20 ProjectionTy, Substitution, TraitRef, Ty, TyKind,
19}; 21};
20 22
21const AUTODEREF_RECURSION_LIMIT: usize = 10; 23const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -25,9 +27,9 @@ pub fn autoderef<'a>(
25 krate: Option<CrateId>, 27 krate: Option<CrateId>,
26 ty: InEnvironment<Canonical<Ty>>, 28 ty: InEnvironment<Canonical<Ty>>,
27) -> impl Iterator<Item = Canonical<Ty>> + 'a { 29) -> impl Iterator<Item = Canonical<Ty>> + 'a {
28 let InEnvironment { value: ty, environment } = ty; 30 let InEnvironment { goal: ty, environment } = ty;
29 successors(Some(ty), move |ty| { 31 successors(Some(ty), move |ty| {
30 deref(db, krate?, InEnvironment { value: ty, environment: environment.clone() }) 32 deref(db, krate?, InEnvironment { goal: ty, environment: environment.clone() })
31 }) 33 })
32 .take(AUTODEREF_RECURSION_LIMIT) 34 .take(AUTODEREF_RECURSION_LIMIT)
33} 35}
@@ -37,8 +39,8 @@ pub(crate) fn deref(
37 krate: CrateId, 39 krate: CrateId,
38 ty: InEnvironment<&Canonical<Ty>>, 40 ty: InEnvironment<&Canonical<Ty>>,
39) -> Option<Canonical<Ty>> { 41) -> Option<Canonical<Ty>> {
40 if let Some(derefed) = ty.value.value.builtin_deref() { 42 if let Some(derefed) = ty.goal.value.builtin_deref() {
41 Some(Canonical { value: derefed, kinds: ty.value.kinds.clone() }) 43 Some(Canonical { value: derefed, binders: ty.goal.binders.clone() })
42 } else { 44 } else {
43 deref_by_trait(db, krate, ty) 45 deref_by_trait(db, krate, ty)
44 } 46 }
@@ -65,14 +67,15 @@ fn deref_by_trait(
65 // FIXME make the Canonical / bound var handling nicer 67 // FIXME make the Canonical / bound var handling nicer
66 68
67 let parameters = 69 let parameters =
68 Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); 70 Substitution::build_for_generics(&generic_params).push(ty.goal.value.clone()).build();
69 71
70 // Check that the type implements Deref at all 72 // Check that the type implements Deref at all
71 let trait_ref = TraitRef { trait_: deref_trait, substs: parameters.clone() }; 73 let trait_ref =
74 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
72 let implements_goal = Canonical { 75 let implements_goal = Canonical {
73 kinds: ty.value.kinds.clone(), 76 binders: ty.goal.binders.clone(),
74 value: InEnvironment { 77 value: InEnvironment {
75 value: Obligation::Trait(trait_ref), 78 goal: trait_ref.cast(&Interner),
76 environment: ty.environment.clone(), 79 environment: ty.environment.clone(),
77 }, 80 },
78 }; 81 };
@@ -81,23 +84,32 @@ fn deref_by_trait(
81 } 84 }
82 85
83 // Now do the assoc type projection 86 // Now do the assoc type projection
84 let projection = super::traits::ProjectionPredicate { 87 let projection = AliasEq {
85 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())) 88 alias: AliasTy::Projection(ProjectionTy {
86 .intern(&Interner),
87 projection_ty: super::ProjectionTy {
88 associated_ty_id: to_assoc_type_id(target), 89 associated_ty_id: to_assoc_type_id(target),
89 substitution: parameters, 90 substitution: parameters,
90 }, 91 }),
92 ty: TyKind::BoundVar(BoundVar::new(
93 DebruijnIndex::INNERMOST,
94 ty.goal.binders.len(&Interner),
95 ))
96 .intern(&Interner),
91 }; 97 };
92 98
93 let obligation = super::Obligation::Projection(projection); 99 let obligation = projection.cast(&Interner);
94 100
95 let in_env = InEnvironment { value: obligation, environment: ty.environment }; 101 let in_env = InEnvironment { goal: obligation, environment: ty.environment };
96 102
97 let canonical = Canonical::new( 103 let canonical = Canonical {
98 in_env, 104 value: in_env,
99 ty.value.kinds.iter().copied().chain(Some(chalk_ir::TyVariableKind::General)), 105 binders: CanonicalVarKinds::from_iter(
100 ); 106 &Interner,
107 ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new(
108 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
109 chalk_ir::UniverseIndex::ROOT,
110 ))),
111 ),
112 };
101 113
102 let solution = db.trait_solve(krate, canonical)?; 114 let solution = db.trait_solve(krate, canonical)?;
103 115
@@ -118,21 +130,21 @@ fn deref_by_trait(
118 // assumptions will be broken. We would need to properly introduce 130 // assumptions will be broken. We would need to properly introduce
119 // new variables in that case 131 // new variables in that case
120 132
121 for i in 1..vars.0.kinds.len() { 133 for i in 1..vars.0.binders.len(&Interner) {
122 if vars.0.value[i - 1].interned(&Interner) 134 if vars.0.value[i - 1].interned(&Interner)
123 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 135 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
124 { 136 {
125 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); 137 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
126 return None; 138 return None;
127 } 139 }
128 }