From 292ba6a1f81fee4170c3081f74499fe8c3ddedd4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Apr 2020 22:41:14 +0200 Subject: Remove dead code, which elaborately pretends to be alive --- crates/ra_hir_def/src/body/lower.rs | 4 ---- 1 file changed, 4 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 571603854..f467ed3fe 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -182,10 +182,6 @@ impl ExprCollector<'_> { self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) } - ast::Expr::TryBlockExpr(e) => { - let body = self.collect_block_opt(e.body()); - self.alloc_expr(Expr::TryBlock { body }, syntax_ptr) - } ast::Expr::BlockExpr(e) => self.collect_block(e), ast::Expr::LoopExpr(e) => { let body = self.collect_block_opt(e.loop_body()); -- cgit v1.2.3 From 14126349be47ee28e7feb1ebb2dd1f0392537e56 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Apr 2020 22:44:42 +0200 Subject: Kill more zombies --- crates/ra_hir_def/src/expr.rs | 4 ---- 1 file changed, 4 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs index a0cdad529..aad12e123 100644 --- a/crates/ra_hir_def/src/expr.rs +++ b/crates/ra_hir_def/src/expr.rs @@ -101,9 +101,6 @@ pub enum Expr { Try { expr: ExprId, }, - TryBlock { - body: ExprId, - }, Cast { expr: ExprId, type_ref: TypeRef, @@ -239,7 +236,6 @@ impl Expr { f(*expr); } } - Expr::TryBlock { body } => f(*body), Expr::Loop { body } => f(*body), Expr::While { condition, body } => { f(*condition); -- cgit v1.2.3 From e4267967a8ee3b35d902931cecf06bb4e19f86c5 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 1 May 2020 11:23:03 +0800 Subject: Support local_inner_macros --- crates/ra_hir_def/src/body/lower.rs | 1 + crates/ra_hir_def/src/nameres/collector.rs | 2 ++ crates/ra_hir_def/src/nameres/raw.rs | 27 +++++++++++++++++++++------ crates/ra_hir_def/src/path/lower.rs | 19 ++++++++++++++++++- 4 files changed, 42 insertions(+), 7 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index f467ed3fe..8c1aefbf5 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -430,6 +430,7 @@ impl ExprCollector<'_> { krate: Some(self.expander.module.krate), ast_id: Some(self.expander.ast_id(&e)), kind: MacroDefKind::Declarative, + local_inner: false, }; self.body.item_scope.define_legacy_macro(name, mac); diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 98c74fe25..bf3968bd6 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -204,6 +204,7 @@ impl DefCollector<'_> { ast_id: None, krate: Some(krate), kind: MacroDefKind::CustomDerive(expander), + local_inner: false, }; self.define_proc_macro(name.clone(), macro_id); @@ -941,6 +942,7 @@ impl ModCollector<'_, '_> { ast_id: Some(ast_id.ast_id), krate: Some(self.def_collector.def_map.krate), kind: MacroDefKind::Declarative, + local_inner: mac.local_inner, }; self.def_collector.define_macro(self.module_id, name.clone(), macro_id, mac.export); } diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 39b011ad7..aed9dcc72 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -188,6 +188,7 @@ pub(super) struct MacroData { pub(super) path: ModPath, pub(super) name: Option, pub(super) export: bool, + pub(super) local_inner: bool, pub(super) builtin: bool, } @@ -401,14 +402,28 @@ impl RawItemsCollector { let name = m.name().map(|it| it.as_name()); let ast_id = self.source_ast_id_map.ast_id(&m); - // FIXME: cfg_attr - let export = m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "macro_export"); // FIXME: cfg_attr - let builtin = - m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "rustc_builtin_macro"); - - let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export, builtin }); + let export = attrs.by_key("macro_export").exists(); + let local_inner = + attrs.by_key("macro_export").tt_values().map(|it| &it.token_trees).flatten().any( + |it| match it { + tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { + ident.text.contains("local_inner_macros") + } + _ => false, + }, + ); + let builtin = attrs.by_key("rustc_builtin_macro").exists(); + + let m = self.raw_items.macros.alloc(MacroData { + ast_id, + path, + name, + export, + local_inner, + builtin, + }); self.push_item(current_module, attrs, RawItemKind::Macro(m)); } diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs index 9ec2e0dcd..e632f1afb 100644 --- a/crates/ra_hir_def/src/path/lower.rs +++ b/crates/ra_hir_def/src/path/lower.rs @@ -9,7 +9,10 @@ use hir_expand::{ hygiene::Hygiene, name::{name, AsName}, }; -use ra_syntax::ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner}; +use ra_syntax::{ + ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner}, + T, +}; use super::AssociatedTypeBinding; use crate::{ @@ -113,6 +116,20 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option } segments.reverse(); generic_args.reverse(); + + // handle local_inner_macros : + // Basically, even in rustc it is quite hacky: + // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456 + // We follow what it did anyway :) + if segments.len() == 1 && kind == PathKind::Plain { + let next = path.syntax().last_token().and_then(|it| it.next_token()); + if next.map_or(false, |it| it.kind() == T![!]) { + if let Some(crate_id) = hygiene.local_inner_macros() { + kind = PathKind::DollarCrate(crate_id); + } + } + } + let mod_path = ModPath { kind, segments }; return Some(Path { type_anchor, mod_path, generic_args }); -- cgit v1.2.3 From bdcf6f56589f8367c8cc82f3f4f045dcaf53748d Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Thu, 30 Apr 2020 18:20:13 +0800 Subject: Introduce LowerCtx for path lowering --- crates/ra_hir_def/src/adt.rs | 18 +++++++--- crates/ra_hir_def/src/body.rs | 2 ++ crates/ra_hir_def/src/body/lower.rs | 42 ++++++++++++++++++----- crates/ra_hir_def/src/data.rs | 21 +++++++----- crates/ra_hir_def/src/generics.rs | 68 +++++++++++++++++++++++++------------ crates/ra_hir_def/src/path.rs | 5 +-- crates/ra_hir_def/src/path/lower.rs | 23 ++++++++----- crates/ra_hir_def/src/type_ref.rs | 52 ++++++++++++++++------------ 8 files changed, 158 insertions(+), 73 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 753becc3d..8eef51828 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -12,9 +12,15 @@ use ra_prof::profile; use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner}; use crate::{ - body::CfgExpander, db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, - type_ref::TypeRef, visibility::RawVisibility, EnumId, HasModule, LocalEnumVariantId, - LocalFieldId, Lookup, ModuleId, StructId, UnionId, VariantId, + body::{CfgExpander, LowerCtx}, + db::DefDatabase, + src::HasChildSource, + src::HasSource, + trace::Trace, + type_ref::TypeRef, + visibility::RawVisibility, + EnumId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId, + VariantId, }; /// Note that we use `StructData` for unions as well! @@ -198,6 +204,8 @@ fn lower_struct( trace: &mut Trace>, ast: &InFile, ) -> StructKind { + let ctx = LowerCtx::new(db, ast.file_id); + match &ast.value { ast::StructKind::Tuple(fl) => { for (i, fd) in fl.fields().enumerate() { @@ -210,7 +218,7 @@ fn lower_struct( || Either::Left(fd.clone()), || FieldData { name: Name::new_tuple_field(i), - type_ref: TypeRef::from_ast_opt(fd.type_ref()), + type_ref: TypeRef::from_ast_opt(&ctx, fd.type_ref()), visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())), }, ); @@ -228,7 +236,7 @@ fn lower_struct( || Either::Right(fd.clone()), || FieldData { name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing), - type_ref: TypeRef::from_ast_opt(fd.ascribed_type()), + type_ref: TypeRef::from_ast_opt(&ctx, fd.ascribed_type()), visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())), }, ); diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 890cefcaf..4edaad960 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -15,6 +15,8 @@ use ra_prof::profile; use ra_syntax::{ast, AstNode, AstPtr}; use rustc_hash::FxHashMap; +pub(crate) use lower::LowerCtx; + use crate::{ attr::Attrs, db::DefDatabase, diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index f467ed3fe..e9dd65b0a 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -3,8 +3,9 @@ use either::Either; use hir_expand::{ + hygiene::Hygiene, name::{name, AsName, Name}, - MacroDefId, MacroDefKind, + HirFileId, MacroDefId, MacroDefKind, }; use ra_arena::Arena; use ra_syntax::{ @@ -26,7 +27,7 @@ use crate::{ LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, }, item_scope::BuiltinShadowMode, - path::GenericArgs, + path::{GenericArgs, Path}, type_ref::{Mutability, TypeRef}, AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, @@ -35,6 +36,23 @@ use crate::{ use super::{ExprSource, PatSource}; use ast::AstChildren; +pub(crate) struct LowerCtx { + hygiene: Hygiene, +} + +impl LowerCtx { + pub fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self { + LowerCtx { hygiene: Hygiene::new(db.upcast(), file_id) } + } + pub fn with_hygiene(hygiene: &Hygiene) -> Self { + LowerCtx { hygiene: hygiene.clone() } + } + + pub fn lower_path(&self, ast: ast::Path) -> Option { + Path::from_src(ast, &self.hygiene) + } +} + pub(super) fn lower( db: &dyn DefDatabase, def: DefWithBodyId, @@ -42,10 +60,13 @@ pub(super) fn lower( params: Option, body: Option, ) -> (Body, BodySourceMap) { + let ctx = LowerCtx::new(db, expander.current_file_id.clone()); + ExprCollector { db, def, expander, + ctx, source_map: BodySourceMap::default(), body: Body { exprs: Arena::default(), @@ -62,7 +83,7 @@ struct ExprCollector<'a> { db: &'a dyn DefDatabase, def: DefWithBodyId, expander: Expander, - + ctx: LowerCtx, body: Body, source_map: BodySourceMap, } @@ -237,7 +258,8 @@ impl ExprCollector<'_> { Vec::new() }; let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); - let generic_args = e.type_arg_list().and_then(GenericArgs::from_ast); + let generic_args = + e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx, it)); self.alloc_expr( Expr::MethodCall { receiver, method_name, args, generic_args }, syntax_ptr, @@ -343,7 +365,7 @@ impl ExprCollector<'_> { } ast::Expr::CastExpr(e) => { let expr = self.collect_expr_opt(e.expr()); - let type_ref = TypeRef::from_ast_opt(e.type_ref()); + let type_ref = TypeRef::from_ast_opt(&self.ctx, e.type_ref()); self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) } ast::Expr::RefExpr(e) => { @@ -365,12 +387,16 @@ impl ExprCollector<'_> { if let Some(pl) = e.param_list() { for param in pl.params() { let pat = self.collect_pat_opt(param.pat()); - let type_ref = param.ascribed_type().map(TypeRef::from_ast); + let type_ref = + param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); args.push(pat); arg_types.push(type_ref); } } - let ret_type = e.ret_type().and_then(|r| r.type_ref()).map(TypeRef::from_ast); + let ret_type = e + .ret_type() + .and_then(|r| r.type_ref()) + .map(|it| TypeRef::from_ast(&self.ctx, it)); let body = self.collect_expr_opt(e.body()); self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) } @@ -476,7 +502,7 @@ impl ExprCollector<'_> { .map(|s| match s { ast::Stmt::LetStmt(stmt) => { let pat = self.collect_pat_opt(stmt.pat()); - let type_ref = stmt.ascribed_type().map(TypeRef::from_ast); + let type_ref = stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); let initializer = stmt.initializer().map(|e| self.collect_expr(e)); Statement::Let { pat, type_ref, initializer } } diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index ccb682f9a..7a2067e49 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -15,6 +15,7 @@ use ra_syntax::ast::{ use crate::{ attr::Attrs, + body::LowerCtx, db::DefDatabase, path::{path, AssociatedTypeBinding, GenericArgs, Path}, src::HasSource, @@ -40,13 +41,14 @@ impl FunctionData { pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc { let loc = func.lookup(db); let src = loc.source(db); + let ctx = LowerCtx::new(db, src.file_id); let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); let mut params = Vec::new(); let mut has_self_param = false; if let Some(param_list) = src.value.param_list() { if let Some(self_param) = param_list.self_param() { let self_type = if let Some(type_ref) = self_param.ascribed_type() { - TypeRef::from_ast(type_ref) + TypeRef::from_ast(&ctx, type_ref) } else { let self_type = TypeRef::Path(name![Self].into()); match self_param.kind() { @@ -63,14 +65,14 @@ impl FunctionData { has_self_param = true; } for param in param_list.params() { - let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); + let type_ref = TypeRef::from_ast_opt(&ctx, param.ascribed_type()); params.push(type_ref); } } let attrs = Attrs::new(&src.value, &Hygiene::new(db.upcast(), src.file_id)); let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { - TypeRef::from_ast(type_ref) + TypeRef::from_ast(&ctx, type_ref) } else { TypeRef::unit() }; @@ -122,7 +124,8 @@ impl TypeAliasData { let loc = typ.lookup(db); let node = loc.source(db); let name = node.value.name().map_or_else(Name::missing, |n| n.as_name()); - let type_ref = node.value.type_ref().map(TypeRef::from_ast); + let lower_ctx = LowerCtx::new(db, node.file_id); + let type_ref = node.value.type_ref().map(|it| TypeRef::from_ast(&lower_ctx, it)); let vis_default = RawVisibility::default_for_container(loc.container); let visibility = RawVisibility::from_ast_with_default( db, @@ -130,7 +133,7 @@ impl TypeAliasData { node.as_ref().map(|n| n.visibility()), ); let bounds = if let Some(bound_list) = node.value.type_bound_list() { - bound_list.bounds().map(TypeBound::from_ast).collect() + bound_list.bounds().map(|it| TypeBound::from_ast(&lower_ctx, it)).collect() } else { Vec::new() }; @@ -223,9 +226,10 @@ impl ImplData { let _p = profile("impl_data_query"); let impl_loc = id.lookup(db); let src = impl_loc.source(db); + let lower_ctx = LowerCtx::new(db, src.file_id); - let target_trait = src.value.target_trait().map(TypeRef::from_ast); - let target_type = TypeRef::from_ast_opt(src.value.target_type()); + let target_trait = src.value.target_trait().map(|it| TypeRef::from_ast(&lower_ctx, it)); + let target_type = TypeRef::from_ast_opt(&lower_ctx, src.value.target_type()); let is_negative = src.value.excl_token().is_some(); let module_id = impl_loc.container.module(db); @@ -279,8 +283,9 @@ impl ConstData { vis_default: RawVisibility, node: InFile, ) -> ConstData { + let ctx = LowerCtx::new(db, node.file_id); let name = node.value.name().map(|n| n.as_name()); - let type_ref = TypeRef::from_ast_opt(node.value.ascribed_type()); + let type_ref = TypeRef::from_ast_opt(&ctx, node.value.ascribed_type()); let visibility = RawVisibility::from_ast_with_default(db, vis_default, node.map(|n| n.visibility())); ConstData { name, type_ref, visibility } diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index d850244c4..09a5241f7 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -15,6 +15,7 @@ use ra_prof::profile; use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; use crate::{ + body::LowerCtx, child_by_source::ChildBySource, db::DefDatabase, dyn_map::DynMap, @@ -80,11 +81,13 @@ impl GenericParams { fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile) { let mut generics = GenericParams { types: Arena::default(), where_predicates: Vec::new() }; let mut sm = ArenaMap::default(); + // FIXME: add `: Sized` bound for everything except for `Self` in traits let file_id = match def { GenericDefId::FunctionId(it) => { let src = it.lookup(db).source(db); - generics.fill(&mut sm, &src.value); + let lower_ctx = LowerCtx::new(db, src.file_id); + generics.fill(&lower_ctx, &mut sm, &src.value); // lower `impl Trait` in arguments let data = db.function_data(it); for param in &data.params { @@ -94,21 +97,25 @@ impl GenericParams { } GenericDefId::AdtId(AdtId::StructId(it)) => { let src = it.lookup(db).source(db); - generics.fill(&mut sm, &src.value); + let lower_ctx = LowerCtx::new(db, src.file_id); + generics.fill(&lower_ctx, &mut sm, &src.value); src.file_id } GenericDefId::AdtId(AdtId::UnionId(it)) => { let src = it.lookup(db).source(db); - generics.fill(&mut sm, &src.value); + let lower_ctx = LowerCtx::new(db, src.file_id); + generics.fill(&lower_ctx, &mut sm, &src.value); src.file_id } GenericDefId::AdtId(AdtId::EnumId(it)) => { let src = it.lookup(db).source(db); - generics.fill(&mut sm, &src.value); + let lower_ctx = LowerCtx::new(db, src.file_id); + generics.fill(&lower_ctx, &mut sm, &src.value); src.file_id } GenericDefId::TraitId(it) => { let src = it.lookup(db).source(db); + let lower_ctx = LowerCtx::new(db, src.file_id); // traits get the Self type as an implicit first type parameter let self_param_id = generics.types.alloc(TypeParamData { @@ -120,14 +127,16 @@ impl GenericParams { // add super traits as bounds on Self // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar let self_param = TypeRef::Path(name![Self].into()); - generics.fill_bounds(&src.value, self_param); + generics.fill_bounds(&lower_ctx, &src.value, self_param); - generics.fill(&mut sm, &src.value); + generics.fill(&lower_ctx, &mut sm, &src.value); src.file_id } GenericDefId::TypeAliasId(it) => { let src = it.lookup(db).source(db); - generics.fill(&mut sm, &src.value); + let lower_ctx = LowerCtx::new(db, src.file_id); + + generics.fill(&lower_ctx, &mut sm, &src.value); src.file_id } // Note that we don't add `Self` here: in `impl`s, `Self` is not a @@ -135,7 +144,9 @@ impl GenericParams { // type, so this is handled by the resolver. GenericDefId::ImplId(it) => { let src = it.lookup(db).source(db); - generics.fill(&mut sm, &src.value); + let lower_ctx = LowerCtx::new(db, src.file_id); + + generics.fill(&lower_ctx, &mut sm, &src.value); src.file_id } // We won't be using this ID anyway @@ -145,28 +156,38 @@ impl GenericParams { (generics, InFile::new(file_id, sm)) } - fn fill(&mut self, sm: &mut SourceMap, node: &dyn TypeParamsOwner) { + fn fill(&mut self, lower_ctx: &LowerCtx, sm: &mut SourceMap, node: &dyn TypeParamsOwner) { if let Some(params) = node.type_param_list() { - self.fill_params(sm, params) + self.fill_params(lower_ctx, sm, params) } if let Some(where_clause) = node.where_clause() { - self.fill_where_predicates(where_clause); + self.fill_where_predicates(lower_ctx, where_clause); } } - fn fill_bounds(&mut self, node: &dyn ast::TypeBoundsOwner, type_ref: TypeRef) { + fn fill_bounds( + &mut self, + lower_ctx: &LowerCtx, + node: &dyn ast::TypeBoundsOwner, + type_ref: TypeRef, + ) { for bound in node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) { - self.add_where_predicate_from_bound(bound, type_ref.clone()); + self.add_where_predicate_from_bound(lower_ctx, bound, type_ref.clone()); } } - fn fill_params(&mut self, sm: &mut SourceMap, params: ast::TypeParamList) { + fn fill_params( + &mut self, + lower_ctx: &LowerCtx, + sm: &mut SourceMap, + params: ast::TypeParamList, + ) { for type_param in params.type_params() { let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); // FIXME: Use `Path::from_src` - let default = type_param.default_type().map(TypeRef::from_ast); + let default = type_param.default_type().map(|it| TypeRef::from_ast(lower_ctx, it)); let param = TypeParamData { name: Some(name.clone()), default, @@ -176,29 +197,34 @@ impl GenericParams { sm.insert(param_id, Either::Right(type_param.clone())); let type_ref = TypeRef::Path(name.into()); - self.fill_bounds(&type_param, type_ref); + self.fill_bounds(&lower_ctx, &type_param, type_ref); } } - fn fill_where_predicates(&mut self, where_clause: ast::WhereClause) { + fn fill_where_predicates(&mut self, lower_ctx: &LowerCtx, where_clause: ast::WhereClause) { for pred in where_clause.predicates() { let type_ref = match pred.type_ref() { Some(type_ref) => type_ref, None => continue, }; - let type_ref = TypeRef::from_ast(type_ref); + let type_ref = TypeRef::from_ast(lower_ctx, type_ref); for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { - self.add_where_predicate_from_bound(bound, type_ref.clone()); + self.add_where_predicate_from_bound(lower_ctx, bound, type_ref.clone()); } } } - fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) { + fn add_where_predicate_from_bound( + &mut self, + lower_ctx: &LowerCtx, + bound: ast::TypeBound, + type_ref: TypeRef, + ) { if bound.question_token().is_some() { // FIXME: remove this bound return; } - let bound = TypeBound::from_ast(bound); + let bound = TypeBound::from_ast(lower_ctx, bound); self.where_predicates .push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound }); } diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 162b3c8c7..e84efe2ab 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -7,6 +7,7 @@ use std::{ sync::Arc, }; +use crate::body::LowerCtx; use hir_expand::{ hygiene::Hygiene, name::{AsName, Name}, @@ -244,8 +245,8 @@ impl<'a> PathSegments<'a> { } impl GenericArgs { - pub(crate) fn from_ast(node: ast::TypeArgList) -> Option { - lower::lower_generic_args(node) + pub(crate) fn from_ast(lower_ctx: &LowerCtx, node: ast::TypeArgList) -> Option { + lower::lower_generic_args(lower_ctx, node) } pub(crate) fn empty() -> GenericArgs { diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs index 9ec2e0dcd..e3d237a0a 100644 --- a/crates/ra_hir_def/src/path/lower.rs +++ b/crates/ra_hir_def/src/path/lower.rs @@ -13,6 +13,7 @@ use ra_syntax::ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner}; use super::AssociatedTypeBinding; use crate::{ + body::LowerCtx, path::{GenericArg, GenericArgs, ModPath, Path, PathKind}, type_ref::{TypeBound, TypeRef}, }; @@ -26,6 +27,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option let mut type_anchor = None; let mut segments = Vec::new(); let mut generic_args = Vec::new(); + let ctx = LowerCtx::with_hygiene(hygiene); loop { let segment = path.segment()?; @@ -40,9 +42,10 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option Either::Left(name) => { let args = segment .type_arg_list() - .and_then(lower_generic_args) + .and_then(|it| lower_generic_args(&ctx, it)) .or_else(|| { lower_generic_args_from_fn_path( + &ctx, segment.param_list(), segment.ret_type(), ) @@ -60,7 +63,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option ast::PathSegmentKind::Type { type_ref, trait_ref } => { assert!(path.qualifier().is_none()); // this can only occur at the first segment - let self_type = TypeRef::from_ast(type_ref?); + let self_type = TypeRef::from_ast(&ctx, type_ref?); match trait_ref { // ::foo @@ -128,10 +131,13 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option } } -pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option { +pub(super) fn lower_generic_args( + lower_ctx: &LowerCtx, + node: ast::TypeArgList, +) -> Option { let mut args = Vec::new(); for type_arg in node.type_args() { - let type_ref = TypeRef::from_ast_opt(type_arg.type_ref()); + let type_ref = TypeRef::from_ast_opt(lower_ctx, type_arg.type_ref()); args.push(GenericArg::Type(type_ref)); } // lifetimes ignored for now @@ -140,9 +146,9 @@ pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg; if let Some(name_ref) = assoc_type_arg.name_ref() { let name = name_ref.as_name(); - let type_ref = assoc_type_arg.type_ref().map(TypeRef::from_ast); + let type_ref = assoc_type_arg.type_ref().map(|it| TypeRef::from_ast(lower_ctx, it)); let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { - l.bounds().map(TypeBound::from_ast).collect() + l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect() } else { Vec::new() }; @@ -159,6 +165,7 @@ pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option /// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) /// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). fn lower_generic_args_from_fn_path( + ctx: &LowerCtx, params: Option, ret_type: Option, ) -> Option { @@ -167,14 +174,14 @@ fn lower_generic_args_from_fn_path( if let Some(params) = params { let mut param_types = Vec::new(); for param in params.params() { - let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); + let type_ref = TypeRef::from_ast_opt(&ctx, param.ascribed_type()); param_types.push(type_ref); } let arg = GenericArg::Type(TypeRef::Tuple(param_types)); args.push(arg); } if let Some(ret_type) = ret_type { - let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); + let type_ref = TypeRef::from_ast_opt(&ctx, ret_type.type_ref()); bindings.push(AssociatedTypeBinding { name: name![Output], type_ref: Some(type_ref), diff --git a/crates/ra_hir_def/src/type_ref.rs b/crates/ra_hir_def/src/type_ref.rs index f308c6bdf..5bdad9efd 100644 --- a/crates/ra_hir_def/src/type_ref.rs +++ b/crates/ra_hir_def/src/type_ref.rs @@ -3,7 +3,7 @@ use ra_syntax::ast::{self, TypeAscriptionOwner, TypeBoundsOwner}; -use crate::path::Path; +use crate::{body::LowerCtx, path::Path}; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum Mutability { @@ -64,30 +64,34 @@ pub enum TypeBound { impl TypeRef { /// Converts an `ast::TypeRef` to a `hir::TypeRef`. - pub(crate) fn from_ast(node: ast::TypeRef) -> Self { + pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::TypeRef) -> Self { match node { - ast::TypeRef::ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()), + ast::TypeRef::ParenType(inner) => TypeRef::from_ast_opt(&ctx, inner.type_ref()), ast::TypeRef::TupleType(inner) => { - TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()) + TypeRef::Tuple(inner.fields().map(|it| TypeRef::from_ast(ctx, it)).collect()) } ast::TypeRef::NeverType(..) => TypeRef::Never, ast::TypeRef::PathType(inner) => { // FIXME: Use `Path::from_src` - inner.path().and_then(Path::from_ast).map(TypeRef::Path).unwrap_or(TypeRef::Error) + inner + .path() + .and_then(|it| ctx.lower_path(it)) + .map(TypeRef::Path) + .unwrap_or(TypeRef::Error) } ast::TypeRef::PointerType(inner) => { - let inner_ty = TypeRef::from_ast_opt(inner.type_ref()); + let inner_ty = TypeRef::from_ast_opt(&ctx, inner.type_ref()); let mutability = Mutability::from_mutable(inner.mut_token().is_some()); TypeRef::RawPtr(Box::new(inner_ty), mutability) } ast::TypeRef::ArrayType(inner) => { - TypeRef::Array(Box::new(TypeRef::from_ast_opt(inner.type_ref()))) + TypeRef::Array(Box::new(TypeRef::from_ast_opt(&ctx, inner.type_ref()))) } ast::TypeRef::SliceType(inner) => { - TypeRef::Slice(Box::new(TypeRef::from_ast_opt(inner.type_ref()))) + TypeRef::Slice(Box::new(TypeRef::from_ast_opt(&ctx, inner.type_ref()))) } ast::TypeRef::ReferenceType(inner) => { - let inner_ty = TypeRef::from_ast_opt(inner.type_ref()); + let inner_ty = TypeRef::from_ast_opt(&ctx, inner.type_ref()); let mutability = Mutability::from_mutable(inner.mut_token().is_some()); TypeRef::Reference(Box::new(inner_ty), mutability) } @@ -96,10 +100,13 @@ impl TypeRef { let ret_ty = inner .ret_type() .and_then(|rt| rt.type_ref()) - .map(TypeRef::from_ast) + .map(|it| TypeRef::from_ast(ctx, it)) .unwrap_or_else(|| TypeRef::Tuple(Vec::new())); let mut params = if let Some(pl) = inner.param_list() { - pl.params().map(|p| p.ascribed_type()).map(TypeRef::from_ast_opt).collect() + pl.params() + .map(|p| p.ascribed_type()) + .map(|it| TypeRef::from_ast_opt(&ctx, it)) + .collect() } else { Vec::new() }; @@ -107,19 +114,19 @@ impl TypeRef { TypeRef::Fn(params) } // for types are close enough for our purposes to the inner type for now... - ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(inner.type_ref()), + ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(&ctx, inner.type_ref()), ast::TypeRef::ImplTraitType(inner) => { - TypeRef::ImplTrait(type_bounds_from_ast(inner.type_bound_list())) + TypeRef::ImplTrait(type_bounds_from_ast(ctx, inner.type_bound_list())) } ast::TypeRef::DynTraitType(inner) => { - TypeRef::DynTrait(type_bounds_from_ast(inner.type_bound_list())) + TypeRef::DynTrait(type_bounds_from_ast(ctx, inner.type_bound_list())) } } } - pub(crate) fn from_ast_opt(node: Option) -> Self { + pub(crate) fn from_ast_opt(ctx: &LowerCtx, node: Option) -> Self { if let Some(node) = node { - TypeRef::from_ast(node) + TypeRef::from_ast(ctx, node) } else { TypeRef::Error } @@ -180,24 +187,27 @@ impl TypeRef { } } -pub(crate) fn type_bounds_from_ast(type_bounds_opt: Option) -> Vec { +pub(crate) fn type_bounds_from_ast( + lower_ctx: &LowerCtx, + type_bounds_opt: Option, +) -> Vec { if let Some(type_bounds) = type_bounds_opt { - type_bounds.bounds().map(TypeBound::from_ast).collect() + type_bounds.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect() } else { vec![] } } impl TypeBound { - pub(crate) fn from_ast(node: ast::TypeBound) -> Self { + pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::TypeBound) -> Self { match node.kind() { ast::TypeBoundKind::PathType(path_type) => { let path = match path_type.path() { Some(p) => p, None => return TypeBound::Error, }; - // FIXME: Use `Path::from_src` - let path = match Path::from_ast(path) { + + let path = match ctx.lower_path(path) { Some(p) => p, None => return TypeBound::Error, }; -- cgit v1.2.3 From 7bbdeb43a4972300779a8d30c7323445c1105f44 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 1 May 2020 20:58:24 +0800 Subject: Make AttrQuery copyable --- crates/ra_hir_def/src/attr.rs | 1 + crates/ra_hir_def/src/nameres/raw.rs | 24 ++++++++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 5a86af8ba..576cd0c65 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -140,6 +140,7 @@ impl Attr { } } +#[derive(Debug, Clone, Copy)] pub struct AttrQuery<'a> { attrs: &'a Attrs, key: &'static str, diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index aed9dcc72..a71503c76 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -404,16 +404,20 @@ impl RawItemsCollector { let ast_id = self.source_ast_id_map.ast_id(&m); // FIXME: cfg_attr - let export = attrs.by_key("macro_export").exists(); - let local_inner = - attrs.by_key("macro_export").tt_values().map(|it| &it.token_trees).flatten().any( - |it| match it { - tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { - ident.text.contains("local_inner_macros") - } - _ => false, - }, - ); + let export_attr = attrs.by_key("macro_export"); + + let export = export_attr.exists(); + let local_inner = if export { + export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it { + tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { + ident.text.contains("local_inner_macros") + } + _ => false, + }) + } else { + false + }; + let builtin = attrs.by_key("rustc_builtin_macro").exists(); let m = self.raw_items.macros.alloc(MacroData { -- cgit v1.2.3 From fd030f9450ed6910677e30f8fa65b06e71fcffa2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 2 May 2020 01:12:37 +0200 Subject: Revert "Merge #4233" This reverts commit a5f2b16366f027ad60c58266a66eb7fbdcbda9f9, reversing changes made to c96b2180c1c4206a0a98c280b4d30897eb116336. --- crates/ra_hir_def/src/body/lower.rs | 4 ++++ crates/ra_hir_def/src/expr.rs | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index e9dd65b0a..f06cc115b 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -203,6 +203,10 @@ impl ExprCollector<'_> { self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) } + ast::Expr::TryBlockExpr(e) => { + let body = self.collect_block_opt(e.body()); + self.alloc_expr(Expr::TryBlock { body }, syntax_ptr) + } ast::Expr::BlockExpr(e) => self.collect_block(e), ast::Expr::LoopExpr(e) => { let body = self.collect_block_opt(e.loop_body()); diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs index aad12e123..a0cdad529 100644 --- a/crates/ra_hir_def/src/expr.rs +++ b/crates/ra_hir_def/src/expr.rs @@ -101,6 +101,9 @@ pub enum Expr { Try { expr: ExprId, }, + TryBlock { + body: ExprId, + }, Cast { expr: ExprId, type_ref: TypeRef, @@ -236,6 +239,7 @@ impl Expr { f(*expr); } } + Expr::TryBlock { body } => f(*body), Expr::Loop { body } => f(*body), Expr::While { condition, body } => { f(*condition); -- cgit v1.2.3 From 291d03949bbd1e8f96dcf348e184d91d57204419 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 2 May 2020 10:06:17 +0800 Subject: Add test in name resolutions --- crates/ra_hir_def/src/nameres/tests/macros.rs | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs index b0befdfbd..9bc0e6287 100644 --- a/crates/ra_hir_def/src/nameres/tests/macros.rs +++ b/crates/ra_hir_def/src/nameres/tests/macros.rs @@ -135,6 +135,43 @@ fn macro_rules_export_with_local_inner_macros_are_visible() { "###); } +#[test] +fn local_inner_macros_makes_local_macros_usable() { + let map = def_map( + " + //- /main.rs crate:main deps:foo + foo::structs!(Foo, Bar); + mod bar; + //- /bar.rs + use crate::*; + //- /lib.rs crate:foo + #[macro_export(local_inner_macros)] + macro_rules! structs { + ($($i:ident),*) => { + inner!($($i),*); + } + } + #[macro_export] + macro_rules! inner { + ($($i:ident),*) => { + $(struct $i { field: u32 } )* + } + } + ", + ); + assert_snapshot!(map, @r###" + ⋮crate + ⋮Bar: t v + ⋮Foo: t v + ⋮bar: t + ⋮ + ⋮crate::bar + ⋮Bar: t v + ⋮Foo: t v + ⋮bar: t + "###); +} + #[test] fn unexpanded_macro_should_expand_by_fixedpoint_loop() { let map = def_map( -- cgit v1.2.3 From edf0b4c1528407d5077220191e601ac41f790b99 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 2 May 2020 10:16:26 +0800 Subject: Test whether it is bang macro properly --- crates/ra_hir_def/src/path/lower.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs index e632f1afb..b902cacd1 100644 --- a/crates/ra_hir_def/src/path/lower.rs +++ b/crates/ra_hir_def/src/path/lower.rs @@ -9,10 +9,7 @@ use hir_expand::{ hygiene::Hygiene, name::{name, AsName}, }; -use ra_syntax::{ - ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner}, - T, -}; +use ra_syntax::ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner}; use super::AssociatedTypeBinding; use crate::{ @@ -122,10 +119,11 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456 // We follow what it did anyway :) if segments.len() == 1 && kind == PathKind::Plain { - let next = path.syntax().last_token().and_then(|it| it.next_token()); - if next.map_or(false, |it| it.kind() == T![!]) { - if let Some(crate_id) = hygiene.local_inner_macros() { - kind = PathKind::DollarCrate(crate_id); + if let Some(macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { + if macro_call.is_bang() { + if let Some(crate_id) = hygiene.local_inner_macros() { + kind = PathKind::DollarCrate(crate_id); + } } } } -- cgit v1.2.3 From 4f2134cc33f07c09fe166cec42971828843bc0ef Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 2 May 2020 01:18:19 +0200 Subject: Introduce EffectExpr --- crates/ra_hir_def/src/body/lower.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index f06cc115b..58b3d10d8 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -203,10 +203,16 @@ impl ExprCollector<'_> { self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) } - ast::Expr::TryBlockExpr(e) => { - let body = self.collect_block_opt(e.body()); - self.alloc_expr(Expr::TryBlock { body }, syntax_ptr) - } + ast::Expr::EffectExpr(e) => match e.effect() { + ast::Effect::Try(_) => { + let body = self.collect_block_opt(e.block_expr()); + self.alloc_expr(Expr::TryBlock { body }, syntax_ptr) + } + // FIXME: we need to record these effects somewhere... + ast::Effect::Async(_) | ast::Effect::Label(_) | ast::Effect::Unsafe(_) => { + self.collect_block_opt(e.block_expr()) + } + }, ast::Expr::BlockExpr(e) => self.collect_block(e), ast::Expr::LoopExpr(e) => { let body = self.collect_block_opt(e.loop_body()); @@ -494,12 +500,8 @@ impl ExprCollector<'_> { } } - fn collect_block(&mut self, expr: ast::BlockExpr) -> ExprId { - let syntax_node_ptr = AstPtr::new(&expr.clone().into()); - let block = match expr.block() { - Some(block) => block, - None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), - }; + fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId { + let syntax_node_ptr = AstPtr::new(&block.clone().into()); self.collect_block_items(&block); let statements = block .statements() @@ -517,7 +519,7 @@ impl ExprCollector<'_> { self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) } - fn collect_block_items(&mut self, block: &ast::Block) { + fn collect_block_items(&mut self, block: &ast::BlockExpr) { let container = ContainerId::DefWithBodyId(self.def); for item in block.items() { let (def, name): (ModuleDefId, Option) = match item { -- cgit v1.2.3