Skip to content

Commit

Permalink
Auto merge of #16167 - Veykril:dummy-spans, r=Veykril
Browse files Browse the repository at this point in the history
fix: Fully remove dummy spans

Fixes #16008

Some of these spans are certainly wrong, but since we discard invisible delimiters currently it doesn't really matter.
  • Loading branch information
bors committed Dec 20, 2023
2 parents 65ed198 + f211a40 commit 337e2ab
Show file tree
Hide file tree
Showing 32 changed files with 292 additions and 256 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ lsp-server = { version = "0.7.4" }

# non-local crates
anyhow = "1.0.75"
arrayvec = "0.7.4"
bitflags = "2.4.1"
cargo_metadata = "0.18.1"
command-group = "2.0.1"
Expand Down
10 changes: 5 additions & 5 deletions crates/cfg/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
use arbitrary::{Arbitrary, Unstructured};
use expect_test::{expect, Expect};
use mbe::{syntax_node_to_token_tree, DummyTestSpanMap};
use mbe::{syntax_node_to_token_tree, DummyTestSpanMap, DUMMY};
use syntax::{ast, AstNode};

use crate::{CfgAtom, CfgExpr, CfgOptions, DnfExpr};

fn assert_parse_result(input: &str, expected: CfgExpr) {
let source_file = ast::SourceFile::parse(input).ok().unwrap();
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap);
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap, DUMMY);
let cfg = CfgExpr::parse(&tt);
assert_eq!(cfg, expected);
}

fn check_dnf(input: &str, expect: Expect) {
let source_file = ast::SourceFile::parse(input).ok().unwrap();
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap);
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap, DUMMY);
let cfg = CfgExpr::parse(&tt);
let actual = format!("#![cfg({})]", DnfExpr::new(cfg));
expect.assert_eq(&actual);
Expand All @@ -25,7 +25,7 @@ fn check_dnf(input: &str, expect: Expect) {
fn check_why_inactive(input: &str, opts: &CfgOptions, expect: Expect) {
let source_file = ast::SourceFile::parse(input).ok().unwrap();
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap);
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap, DUMMY);
let cfg = CfgExpr::parse(&tt);
let dnf = DnfExpr::new(cfg);
let why_inactive = dnf.why_inactive(opts).unwrap().to_string();
Expand All @@ -36,7 +36,7 @@ fn check_why_inactive(input: &str, opts: &CfgOptions, expect: Expect) {
fn check_enable_hints(input: &str, opts: &CfgOptions, expected_hints: &[&str]) {
let source_file = ast::SourceFile::parse(input).ok().unwrap();
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap);
let tt = syntax_node_to_token_tree(tt.syntax(), DummyTestSpanMap, DUMMY);
let cfg = CfgExpr::parse(&tt);
let dnf = DnfExpr::new(cfg);
let hints = dnf.compute_enable_hints(opts).map(|diff| diff.to_string()).collect::<Vec<_>>();
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-def/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ rust-version.workspace = true
doctest = false

[dependencies]
arrayvec = "0.7.2"
arrayvec.workspace = true
bitflags.workspace = true
cov-mark = "2.0.0-pre.1"
dashmap.workspace = true
Expand Down
10 changes: 7 additions & 3 deletions crates/hir-def/src/attr/tests.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
//! This module contains tests for doc-expression parsing.
//! Currently, it tests `#[doc(hidden)]` and `#[doc(alias)]`.
use triomphe::Arc;

use base_db::FileId;
use hir_expand::span_map::{RealSpanMap, SpanMapRef};
use hir_expand::span_map::{RealSpanMap, SpanMap};
use mbe::syntax_node_to_token_tree;
use syntax::{ast, AstNode};
use syntax::{ast, AstNode, TextRange};

use crate::attr::{DocAtom, DocExpr};

fn assert_parse_result(input: &str, expected: DocExpr) {
let source_file = ast::SourceFile::parse(input).ok().unwrap();
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
let map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(FileId::from_raw(0))));
let tt = syntax_node_to_token_tree(
tt.syntax(),
SpanMapRef::RealSpanMap(&RealSpanMap::absolute(FileId::from_raw(0))),
map.as_ref(),
map.span_for_range(TextRange::empty(0.into())),
);
let cfg = DocExpr::parse(&tt);
assert_eq!(cfg, expected);
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-def/src/item_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ use la_arena::{Arena, Idx, IdxRange, RawIdx};
use profile::Count;
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use span::SyntaxContextId;
use span::Span;
use stdx::never;
use syntax::{ast, match_ast, SyntaxKind};
use triomphe::Arc;
Expand Down Expand Up @@ -747,7 +747,7 @@ pub struct MacroCall {
pub path: Interned<ModPath>,
pub ast_id: FileAstId<ast::MacroCall>,
pub expand_to: ExpandTo,
pub call_site: SyntaxContextId,
pub call_site: Span,
}

#[derive(Debug, Clone, Eq, PartialEq)]
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-def/src/item_tree/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ impl<'a> Ctx<'a> {
path,
ast_id,
expand_to,
call_site: span_map.span_for_range(m.syntax().text_range()).ctx,
call_site: span_map.span_for_range(m.syntax().text_range()),
};
Some(id(self.data().macro_calls.alloc(res)))
}
Expand Down
14 changes: 7 additions & 7 deletions crates/hir-def/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ use hir_expand::{
use item_tree::ExternBlock;
use la_arena::Idx;
use nameres::DefMap;
use span::SyntaxContextId;
use span::Span;
use stdx::impl_from;
use syntax::{ast, AstNode};

Expand Down Expand Up @@ -1172,7 +1172,7 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
return Ok(ExpandResult::only_err(ExpandError::other("malformed macro invocation")));
};

let call_site = span_map.span_for_range(self.value.syntax().text_range()).ctx;
let call_site = span_map.span_for_range(self.value.syntax().text_range());

macro_call_as_call_id_with_eager(
db,
Expand Down Expand Up @@ -1202,7 +1202,7 @@ impl<T: AstIdNode> AstIdWithPath<T> {
fn macro_call_as_call_id(
db: &dyn ExpandDatabase,
call: &AstIdWithPath<ast::MacroCall>,
call_site: SyntaxContextId,
call_site: Span,
expand_to: ExpandTo,
krate: CrateId,
resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
Expand All @@ -1214,7 +1214,7 @@ fn macro_call_as_call_id(
fn macro_call_as_call_id_with_eager(
db: &dyn ExpandDatabase,
call: &AstIdWithPath<ast::MacroCall>,
call_site: SyntaxContextId,
call_site: Span,
expand_to: ExpandTo,
krate: CrateId,
resolver: impl FnOnce(path::ModPath) -> Option<MacroDefId>,
Expand Down Expand Up @@ -1320,7 +1320,7 @@ fn derive_macro_as_call_id(
item_attr: &AstIdWithPath<ast::Adt>,
derive_attr_index: AttrId,
derive_pos: u32,
call_site: SyntaxContextId,
call_site: Span,
krate: CrateId,
resolver: impl Fn(path::ModPath) -> Option<(MacroId, MacroDefId)>,
) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro> {
Expand Down Expand Up @@ -1350,7 +1350,7 @@ fn attr_macro_as_call_id(
let arg = match macro_attr.input.as_deref() {
Some(AttrInput::TokenTree(tt)) => {
let mut tt = tt.as_ref().clone();
tt.delimiter = tt::Delimiter::DUMMY_INVISIBLE;
tt.delimiter = tt::Delimiter::invisible_spanned(macro_attr.span);
Some(tt)
}

Expand All @@ -1365,7 +1365,7 @@ fn attr_macro_as_call_id(
attr_args: arg.map(Arc::new),
invoc_attr_index: macro_attr.id,
},
macro_attr.ctxt,
macro_attr.span,
)
}

Expand Down
17 changes: 8 additions & 9 deletions crates/hir-def/src/nameres/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,13 @@ enum MacroDirectiveKind {
FnLike {
ast_id: AstIdWithPath<ast::MacroCall>,
expand_to: ExpandTo,
call_site: SyntaxContextId,
call_site: Span,
},
Derive {
ast_id: AstIdWithPath<ast::Adt>,
derive_attr: AttrId,
derive_pos: usize,
call_site: SyntaxContextId,
call_site: Span,
},
Attr {
ast_id: AstIdWithPath<ast::Item>,
Expand Down Expand Up @@ -1307,38 +1307,37 @@ impl DefCollector<'_> {
// Not resolved to a derive helper or the derive attribute, so try to treat as a normal attribute.
let call_id =
attr_macro_as_call_id(self.db, file_ast_id, attr, self.def_map.krate, def);
let loc: MacroCallLoc = self.db.lookup_intern_macro_call(call_id);

// If proc attribute macro expansion is disabled, skip expanding it here
if !self.db.expand_proc_attr_macros() {
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
directive.module_id,
loc.kind,
loc.def.krate,
self.db.lookup_intern_macro_call(call_id).kind,
def.krate,
));
return recollect_without(self);
}

// Skip #[test]/#[bench] expansion, which would merely result in more memory usage
// due to duplicating functions into macro expansions
if matches!(
loc.def.kind,
def.kind,
MacroDefKind::BuiltInAttr(expander, _)
if expander.is_test() || expander.is_bench()
) {
return recollect_without(self);
}

if let MacroDefKind::ProcMacro(exp, ..) = loc.def.kind {
if let MacroDefKind::ProcMacro(exp, ..) = def.kind {
if exp.is_dummy() {
// If there's no expander for the proc macro (e.g.
// because proc macros are disabled, or building the
// proc macro crate failed), report this and skip
// expansion like we would if it was disabled
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
directive.module_id,
loc.kind,
loc.def.krate,
self.db.lookup_intern_macro_call(call_id).kind,
def.krate,
));

return recollect_without(self);
Expand Down
19 changes: 10 additions & 9 deletions crates/hir-expand/src/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use either::Either;
use intern::Interned;
use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
use smallvec::{smallvec, SmallVec};
use span::SyntaxContextId;
use span::Span;
use syntax::{ast, match_ast, AstNode, AstToken, SmolStr, SyntaxNode};
use triomphe::Arc;

Expand Down Expand Up @@ -53,7 +53,7 @@ impl RawAttrs {
id,
input: Some(Interned::new(AttrInput::Literal(SmolStr::new(doc)))),
path: Interned::new(ModPath::from(crate::name!(doc))),
ctxt: span_map.span_for_range(comment.syntax().text_range()).ctx,
span: span_map.span_for_range(comment.syntax().text_range()),
}),
});
let entries: Arc<[Attr]> = Arc::from_iter(entries);
Expand Down Expand Up @@ -120,7 +120,7 @@ impl RawAttrs {
let attrs =
parts.enumerate().take(1 << AttrId::CFG_ATTR_BITS).filter_map(|(idx, attr)| {
let tree = Subtree {
delimiter: tt::Delimiter::dummy_invisible(),
delimiter: tt::Delimiter::invisible_spanned(attr.first()?.first_span()),
token_trees: attr.to_vec(),
};
Attr::from_tt(db, &tree, index.with_cfg_attr(idx))
Expand Down Expand Up @@ -177,7 +177,7 @@ pub struct Attr {
pub id: AttrId,
pub path: Interned<ModPath>,
pub input: Option<Interned<AttrInput>>,
pub ctxt: SyntaxContextId,
pub span: Span,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -206,19 +206,20 @@ impl Attr {
id: AttrId,
) -> Option<Attr> {
let path = Interned::new(ModPath::from_src(db, ast.path()?, span_map)?);
let span = span_map.span_for_range(ast.syntax().text_range());
let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() {
let value = match lit.kind() {
ast::LiteralKind::String(string) => string.value()?.into(),
_ => lit.syntax().first_token()?.text().trim_matches('"').into(),
};
Some(Interned::new(AttrInput::Literal(value)))
} else if let Some(tt) = ast.token_tree() {
let tree = syntax_node_to_token_tree(tt.syntax(), span_map);
let tree = syntax_node_to_token_tree(tt.syntax(), span_map, span);
Some(Interned::new(AttrInput::TokenTree(Box::new(tree))))
} else {
None
};
Some(Attr { id, path, input, ctxt: span_map.span_for_range(ast.syntax().text_range()).ctx })
Some(Attr { id, path, input, span })
}

fn from_tt(db: &dyn ExpandDatabase, tt: &tt::Subtree, id: AttrId) -> Option<Attr> {
Expand Down Expand Up @@ -266,7 +267,7 @@ impl Attr {
pub fn parse_path_comma_token_tree<'a>(
&'a self,
db: &'a dyn ExpandDatabase,
) -> Option<impl Iterator<Item = (ModPath, SyntaxContextId)> + 'a> {
) -> Option<impl Iterator<Item = (ModPath, Span)> + 'a> {
let args = self.token_tree_value()?;

if args.delimiter.kind != DelimiterKind::Parenthesis {
Expand All @@ -282,7 +283,7 @@ impl Attr {
// FIXME: This is necessarily a hack. It'd be nice if we could avoid allocation
// here or maybe just parse a mod path from a token tree directly
let subtree = tt::Subtree {
delimiter: tt::Delimiter::dummy_invisible(),
delimiter: tt::Delimiter::invisible_spanned(tts.first()?.first_span()),
token_trees: tts.to_vec(),
};
let (parse, span_map) =
Expand All @@ -294,7 +295,7 @@ impl Attr {
return None;
}
let path = meta.path()?;
let call_site = span_map.span_at(path.syntax().text_range().start()).ctx;
let call_site = span_map.span_at(path.syntax().text_range().start());
Some((
ModPath::from_src(db, path, SpanMapRef::ExpansionSpanMap(&span_map))?,
call_site,
Expand Down
21 changes: 9 additions & 12 deletions crates/hir-expand/src/builtin_attr_macro.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Builtin attributes.
use span::{FileId, MacroCallId, Span, SyntaxContextId, ROOT_ERASED_FILE_AST_ID};
use syntax::{TextRange, TextSize};
use span::{MacroCallId, Span};

use crate::{db::ExpandDatabase, name, tt, ExpandResult, MacroCallKind};

Expand Down Expand Up @@ -102,28 +101,26 @@ fn derive_attr_expand(
MacroCallKind::Attr { attr_args: Some(attr_args), .. } if loc.def.is_attribute_derive() => {
attr_args
}
_ => return ExpandResult::ok(tt::Subtree::empty(tt::DelimSpan::DUMMY)),
_ => {
return ExpandResult::ok(tt::Subtree::empty(tt::DelimSpan {
open: loc.call_site,
close: loc.call_site,
}))
}
};
pseudo_derive_attr_expansion(tt, derives, loc.call_site)
}

pub fn pseudo_derive_attr_expansion(
tt: &tt::Subtree,
args: &tt::Subtree,
call_site: SyntaxContextId,
call_site: Span,
) -> ExpandResult<tt::Subtree> {
let mk_leaf = |char| {
tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
char,
spacing: tt::Spacing::Alone,
span: Span {
range: TextRange::empty(TextSize::new(0)),
anchor: span::SpanAnchor {
file_id: FileId::BOGUS,
ast_id: ROOT_ERASED_FILE_AST_ID,
},
ctx: call_site,
},
span: call_site,
}))
};

Expand Down
Loading

0 comments on commit 337e2ab

Please sign in to comment.