From 85cc3cfec99a7d232384efae010bfbc8224f1351 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sun, 3 Jan 2021 11:47:57 +0100 Subject: Revert "Proper handling $crate and local_inner_macros" --- crates/hir_def/src/path/lower.rs | 2 +- crates/hir_expand/src/hygiene.rs | 151 +++++------------------------ crates/hir_expand/src/lib.rs | 11 ++- crates/hir_ty/src/tests/macros.rs | 31 ------ crates/mbe/src/mbe_expander/matcher.rs | 2 +- crates/mbe/src/mbe_expander/transcriber.rs | 20 ++-- crates/mbe/src/parser.rs | 11 +-- 7 files changed, 52 insertions(+), 176 deletions(-) (limited to 'crates') diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index 9518ac109..8a01e6eea 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs @@ -123,7 +123,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option // We follow what it did anyway :) if segments.len() == 1 && kind == PathKind::Plain { if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { - if let Some(crate_id) = hygiene.local_inner_macros(path) { + if let Some(crate_id) = hygiene.local_inner_macros() { kind = PathKind::DollarCrate(crate_id); } } diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs index 6042e15b2..7ab0a5e52 100644 --- a/crates/hir_expand/src/hygiene.rs +++ b/crates/hir_expand/src/hygiene.rs @@ -2,94 +2,30 @@ //! //! Specifically, `ast` + `Hygiene` allows you to create a `Name`. Note that, at //! this moment, this is horribly incomplete and handles only `$crate`. -use std::sync::Arc; - -use arena::{Arena, Idx}; use base_db::CrateId; use either::Either; -use mbe::Origin; -use syntax::{ast, AstNode}; +use syntax::ast; use crate::{ db::AstDatabase, name::{AsName, Name}, - ExpansionInfo, HirFileId, HirFileIdRepr, MacroCallId, MacroDefKind, + HirFileId, HirFileIdRepr, MacroCallId, MacroDefKind, }; #[derive(Clone, Debug)] pub struct Hygiene { - frames: Option>, -} - -impl Hygiene { - pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Hygiene { - Hygiene { frames: Some(Arc::new(HygieneFrames::new(db, file_id.clone()))) } - } - - pub fn new_unhygienic() -> Hygiene { - Hygiene { frames: None } - } - - // FIXME: this should just return name - pub fn name_ref_to_name(&self, name_ref: ast::NameRef) -> Either { - if let Some(frames) = &self.frames { - if name_ref.text() == "$crate" { - if let Some(krate) = frames.root_crate(&name_ref) { - return Either::Right(krate); - } - } - } - - Either::Left(name_ref.as_name()) - } - - pub fn local_inner_macros(&self, path: ast::Path) -> Option { - let frames = self.frames.as_ref()?; - - let mut token = path.syntax().first_token()?; - let mut current = frames.first(); - - while let Some((frame, data)) = - current.and_then(|it| Some((it, it.expansion.as_ref()?.map_token_up(&token)?))) - { - let (mapped, origin) = data; - if origin == Origin::Def { - return if frame.local_inner { frame.krate } else { None }; - } - current = Some(&frames.0[frame.call_site?]); - token = mapped.value; - } - None - } -} - -#[derive(Default, Debug)] -struct HygieneFrames(Arena); - -#[derive(Clone, Debug)] -struct HygieneFrame { - expansion: Option, + // This is what `$crate` expands to + def_crate: Option, // Indicate this is a local inner macro local_inner: bool, - krate: Option, - - call_site: Option>, - def_site: Option>, } -impl HygieneFrames { - fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Self { - let mut frames = HygieneFrames::default(); - frames.add(db, file_id); - frames - } - - fn add(&mut self, db: &dyn AstDatabase, file_id: HirFileId) -> Option> { - let (krate, local_inner) = match file_id.0 { +impl Hygiene { + pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Hygiene { + let (def_crate, local_inner) = match file_id.0 { HirFileIdRepr::FileId(_) => (None, false), HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { - MacroCallId::EagerMacro(_id) => (None, false), MacroCallId::LazyMacro(id) => { let loc = db.lookup_intern_macro(id); match loc.def.kind { @@ -100,68 +36,31 @@ impl HygieneFrames { MacroDefKind::ProcMacro(_) => (None, false), } } + MacroCallId::EagerMacro(_id) => (None, false), }, }; - - let expansion = file_id.expansion_info(db); - let expansion = match expansion { - None => { - return Some(self.0.alloc(HygieneFrame { - expansion: None, - local_inner, - krate, - call_site: None, - def_site: None, - })); - } - Some(it) => it, - }; - - let def_site = expansion.def.clone(); - let call_site = expansion.arg.file_id; - let idx = self.0.alloc(HygieneFrame { - expansion: Some(expansion), - local_inner, - krate, - call_site: None, - def_site: None, - }); - - self.0[idx].call_site = self.add(db, call_site); - self.0[idx].def_site = def_site.and_then(|it| self.add(db, it.file_id)); - - Some(idx) + Hygiene { def_crate, local_inner } } - fn first(&self) -> Option<&HygieneFrame> { - self.0.iter().next().map(|it| it.1) + pub fn new_unhygienic() -> Hygiene { + Hygiene { def_crate: None, local_inner: false } } - fn root_crate(&self, name_ref: &ast::NameRef) -> Option { - let mut token = name_ref.syntax().first_token()?; - let first = self.first()?; - let mut result = first.krate; - let mut current = Some(first); - - while let Some((frame, (mapped, origin))) = - current.and_then(|it| Some((it, it.expansion.as_ref()?.map_token_up(&token)?))) - { - result = frame.krate; - - let site = match origin { - Origin::Def => frame.def_site, - Origin::Call => frame.call_site, - }; - - let site = match site { - None => break, - Some(it) => it, - }; - - current = Some(&self.0[site]); - token = mapped.value; + // FIXME: this should just return name + pub fn name_ref_to_name(&self, name_ref: ast::NameRef) -> Either { + if let Some(def_crate) = self.def_crate { + if name_ref.text() == "$crate" { + return Either::Right(def_crate); + } } + Either::Left(name_ref.as_name()) + } - result + pub fn local_inner_macros(&self) -> Option { + if self.local_inner { + self.def_crate + } else { + None + } } } diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index 5b6734a5f..3fa1b1d77 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs @@ -340,8 +340,11 @@ impl ExpansionInfo { Some(self.expanded.with_value(token)) } - pub fn map_token_up(&self, token: &SyntaxToken) -> Option<(InFile, Origin)> { - let token_id = self.exp_map.token_by_range(token.text_range())?; + pub fn map_token_up( + &self, + token: InFile<&SyntaxToken>, + ) -> Option<(InFile, Origin)> { + let token_id = self.exp_map.token_by_range(token.value.text_range())?; let (token_id, origin) = self.macro_def.0.map_id_up(token_id); let (token_map, tt) = match origin { @@ -356,7 +359,7 @@ impl ExpansionInfo { ), }; - let range = token_map.range_by_token(token_id)?.by_kind(token.kind())?; + let range = token_map.range_by_token(token_id)?.by_kind(token.value.kind())?; let token = algo::find_covering_element(&tt.value, range + tt.value.text_range().start()) .into_token()?; Some((tt.with_value(token), origin)) @@ -492,7 +495,7 @@ fn ascend_call_token( expansion: &ExpansionInfo, token: InFile, ) -> Option> { - let (mapped, origin) = expansion.map_token_up(&token.value)?; + let (mapped, origin) = expansion.map_token_up(token.as_ref())?; if origin != Origin::Call { return None; } diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs index c64f0b5b5..1953da7be 100644 --- a/crates/hir_ty/src/tests/macros.rs +++ b/crates/hir_ty/src/tests/macros.rs @@ -370,37 +370,6 @@ expand!(); ); } -#[test] -fn infer_macro_with_dollar_crate_in_def_site() { - check_types( - r#" -//- /main.rs crate:main deps:foo -use foo::expand; - -macro_rules! list { - ($($tt:tt)*) => { $($tt)* } -} - -fn test() { - let r = expand!(); - r; - //^ u128 -} - -//- /lib.rs crate:foo -#[macro_export] -macro_rules! expand { - () => { list!($crate::m!()) }; -} - -#[macro_export] -macro_rules! m { - () => { 0u128 }; -} -"#, - ); -} - #[test] fn infer_type_value_non_legacy_macro_use_as() { check_infer( diff --git a/crates/mbe/src/mbe_expander/matcher.rs b/crates/mbe/src/mbe_expander/matcher.rs index 385b46601..ab5f87c48 100644 --- a/crates/mbe/src/mbe_expander/matcher.rs +++ b/crates/mbe/src/mbe_expander/matcher.rs @@ -150,7 +150,7 @@ fn match_subtree( res.add_err(err!("leftover tokens")); } } - Op::Var { name, kind, .. } => { + Op::Var { name, kind } => { let kind = match kind { Some(k) => k, None => { diff --git a/crates/mbe/src/mbe_expander/transcriber.rs b/crates/mbe/src/mbe_expander/transcriber.rs index 57f3f104d..720531237 100644 --- a/crates/mbe/src/mbe_expander/transcriber.rs +++ b/crates/mbe/src/mbe_expander/transcriber.rs @@ -100,8 +100,8 @@ fn expand_subtree( err = err.or(e); arena.push(tt.into()); } - Op::Var { name, id, .. } => { - let ExpandResult { value: fragment, err: e } = expand_var(ctx, &name, *id); + Op::Var { name, .. } => { + let ExpandResult { value: fragment, err: e } = expand_var(ctx, &name); err = err.or(e); push_fragment(arena, fragment); } @@ -118,10 +118,12 @@ fn expand_subtree( ExpandResult { value: tt::Subtree { delimiter: template.delimiter, token_trees: tts }, err } } -fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr, id: tt::TokenId) -> ExpandResult { +fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult { if v == "crate" { // We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path. - let tt = tt::Leaf::from(tt::Ident { text: "$crate".into(), id }).into(); + let tt = + tt::Leaf::from(tt::Ident { text: "$crate".into(), id: tt::TokenId::unspecified() }) + .into(); ExpandResult::ok(Fragment::Tokens(tt)) } else if !ctx.bindings.contains(v) { // Note that it is possible to have a `$var` inside a macro which is not bound. @@ -140,8 +142,14 @@ fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr, id: tt::TokenId) -> ExpandResult let tt = tt::Subtree { delimiter: None, token_trees: vec![ - tt::Leaf::from(tt::Punct { char: '$', spacing: tt::Spacing::Alone, id }).into(), - tt::Leaf::from(tt::Ident { text: v.clone(), id }).into(), + tt::Leaf::from(tt::Punct { + char: '$', + spacing: tt::Spacing::Alone, + id: tt::TokenId::unspecified(), + }) + .into(), + tt::Leaf::from(tt::Ident { text: v.clone(), id: tt::TokenId::unspecified() }) + .into(), ], } .into(); diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs index 77cc739b6..2f3ebc831 100644 --- a/crates/mbe/src/parser.rs +++ b/crates/mbe/src/parser.rs @@ -8,7 +8,7 @@ use crate::{tt_iter::TtIter, ExpandError, MetaTemplate}; #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) enum Op { - Var { name: SmolStr, kind: Option, id: tt::TokenId }, + Var { name: SmolStr, kind: Option }, Repeat { subtree: MetaTemplate, kind: RepeatKind, separator: Option }, Leaf(tt::Leaf), Subtree(MetaTemplate), @@ -106,21 +106,18 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul } let name = UNDERSCORE.clone(); let kind = eat_fragment_kind(src, mode)?; - let id = punct.id; - Op::Var { name, kind, id } + Op::Var { name, kind } } tt::Leaf::Ident(ident) => { let name = ident.text.clone(); let kind = eat_fragment_kind(src, mode)?; - let id = ident.id; - Op::Var { name, kind, id } + Op::Var { name, kind } } tt::Leaf::Literal(lit) => { if is_boolean_literal(&lit) { let name = lit.text.clone(); let kind = eat_fragment_kind(src, mode)?; - let id = lit.id; - Op::Var { name, kind, id } + Op::Var { name, kind } } else { bail!("bad var 2"); } -- cgit v1.2.3