resolver: &dyn Fn(ModPath) -> Option<MacroDefId>,
diagnostic_sink: &mut dyn FnMut(mbe::ExpandError),
) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
+ let hygiene = Hygiene::new(db, macro_call.file_id);
let parsed_args = macro_call
.value
.token_tree()
let parsed_args = mbe::token_tree_to_syntax_node(&parsed_args, mbe::TopEntryPoint::Expr).0;
let result = match eager_macro_recur(
db,
+ &hygiene,
InFile::new(arg_id.as_file(), parsed_args.syntax_node()),
krate,
resolver,
fn eager_macro_recur(
db: &dyn AstDatabase,
+ hygiene: &Hygiene,
curr: InFile<SyntaxNode>,
krate: CrateId,
macro_resolver: &dyn Fn(ModPath) -> Option<MacroDefId>,
mut diagnostic_sink: &mut dyn FnMut(mbe::ExpandError),
) -> Result<Result<SyntaxNode, ErrorEmitted>, UnresolvedMacro> {
- let hygiene = Hygiene::new(db, curr.file_id);
let original = curr.value.clone_for_update();
let children = original.descendants().filter_map(ast::MacroCall::cast);
};
// replace macro inside
- match eager_macro_recur(db, val, krate, macro_resolver, diagnostic_sink) {
+ let hygiene = Hygiene::new(db, val.file_id);
+ match eager_macro_recur(db, &hygiene, val, krate, macro_resolver, diagnostic_sink) {
Ok(Ok(it)) => it,
Ok(Err(err)) => return Ok(Err(err)),
Err(err) => return Err(err),
);
}
+ #[test]
+ fn eager_macro_concat() {
+ // FIXME: this is incorrectly handling `$crate`, resulting in a wrong diagnostic.
+ // See: https://github.com/rust-analyzer/rust-analyzer/issues/10300
+
+ check_diagnostics(
+ r#"
+//- /lib.rs crate:lib deps:core
+use core::{panic, concat};
+
+mod private {
+ pub use core::concat;
+}
+
+macro_rules! m {
+ () => {
+ panic!(concat!($crate::private::concat!("")));
+ };
+}
+
+fn f() {
+ m!();
+ //^^^^ error: unresolved macro `$crate::private::concat!`
+}
+
+//- /core.rs crate:core
+#[macro_export]
+#[rustc_builtin_macro]
+macro_rules! concat { () => {} }
+
+pub macro panic {
+ ($msg:expr) => (
+ $crate::panicking::panic_str($msg)
+ ),
+}
+ "#,
+ );
+ }
+
#[test]
fn include_macro_should_allow_empty_content() {
let mut config = DiagnosticsConfig::default();