about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-12-02 13:03:46 +0100
committerLukas Wirth <lukastw97@gmail.com>2023-12-02 13:03:46 +0100
commitd2a31acda19b5a94e1b5894f15ef0922bc286ee1 (patch)
tree018316af92f1c7cea12eb45372b4b59f60fdf5a8
parentefa67294ed7d3742d5177b6ff43f077325ba48be (diff)
downloadrust-d2a31acda19b5a94e1b5894f15ef0922bc286ee1.tar.gz
rust-d2a31acda19b5a94e1b5894f15ef0922bc286ee1.zip
Fix macro expansion expression parenthesis wrapping
-rw-r--r--crates/base-db/src/span.rs23
-rw-r--r--crates/hir-def/src/body/lower.rs2
-rw-r--r--crates/hir-def/src/body/tests.rs69
-rw-r--r--crates/hir-def/src/data.rs2
-rw-r--r--crates/hir-def/src/expander.rs8
-rw-r--r--crates/hir-def/src/generics.rs2
-rw-r--r--crates/hir-def/src/macro_expansion_tests/mbe.rs10
-rw-r--r--crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs4
-rw-r--r--crates/hir-def/src/macro_expansion_tests/mbe/regression.rs4
-rw-r--r--crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs6
-rw-r--r--crates/hir-expand/src/db.rs74
-rw-r--r--crates/hir-expand/src/hygiene.rs32
-rw-r--r--crates/hir-expand/src/lib.rs9
-rw-r--r--crates/hir-ty/src/infer/path.rs1
-rw-r--r--crates/hir-ty/src/lower.rs6
-rw-r--r--crates/hir-ty/src/tests.rs1
-rw-r--r--crates/mbe/src/expander/matcher.rs18
-rw-r--r--crates/mbe/src/expander/transcriber.rs11
18 files changed, 218 insertions, 64 deletions
diff --git a/crates/base-db/src/span.rs b/crates/base-db/src/span.rs
index dbccbb382a7..6723bf97fea 100644
--- a/crates/base-db/src/span.rs
+++ b/crates/base-db/src/span.rs
@@ -14,8 +14,25 @@ pub const ROOT_ERASED_FILE_AST_ID: ErasedFileAstId =
 
 pub type SpanData = tt::SpanData<SpanAnchor, SyntaxContextId>;
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct SyntaxContextId(InternId);
+
+impl fmt::Debug for SyntaxContextId {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if *self == Self::SELF_REF {
+            f.debug_tuple("SyntaxContextId")
+                .field(&{
+                    #[derive(Debug)]
+                    #[allow(non_camel_case_types)]
+                    struct SELF_REF;
+                    SELF_REF
+                })
+                .finish()
+        } else {
+            f.debug_tuple("SyntaxContextId").field(&self.0).finish()
+        }
+    }
+}
 crate::impl_intern_key!(SyntaxContextId);
 
 impl fmt::Display for SyntaxContextId {
@@ -30,7 +47,7 @@ impl SyntaxContext for SyntaxContextId {
 // inherent trait impls please tyvm
 impl SyntaxContextId {
     pub const ROOT: Self = SyntaxContextId(unsafe { InternId::new_unchecked(0) });
-    // veykril(HACK): salsa doesn't allow us fetching the id of the current input to be allocated so
+    // veykril(HACK): FIXME salsa doesn't allow us fetching the id of the current input to be allocated so
     // we need a special value that behaves as the current context.
     pub const SELF_REF: Self =
         SyntaxContextId(unsafe { InternId::new_unchecked(InternId::MAX - 1) });
@@ -107,7 +124,7 @@ pub struct MacroFileId {
 
 /// `MacroCallId` identifies a particular macro invocation, like
 /// `println!("Hello, {}", world)`.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct MacroCallId(salsa::InternId);
 crate::impl_intern_key!(MacroCallId);
 
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index e4158d7564b..0466068ec81 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/crates/hir-def/src/body/lower.rs
@@ -1025,7 +1025,7 @@ impl ExprCollector<'_> {
 
                 let id = collector(self, Some(expansion.tree()));
                 self.ast_id_map = prev_ast_id_map;
-                self.expander.exit(self.db, mark);
+                self.expander.exit(mark);
                 id
             }
             None => collector(self, None),
diff --git a/crates/hir-def/src/body/tests.rs b/crates/hir-def/src/body/tests.rs
index 1658757d2b6..048f0a13f0e 100644
--- a/crates/hir-def/src/body/tests.rs
+++ b/crates/hir-def/src/body/tests.rs
@@ -2,6 +2,7 @@ mod block;
 
 use base_db::{fixture::WithFixture, SourceDatabase};
 use expect_test::{expect, Expect};
+use hir_expand::db::ExpandDatabase;
 
 use crate::{test_db::TestDB, ModuleDefId};
 
@@ -143,7 +144,6 @@ mod m {
 
 #[test]
 fn desugar_builtin_format_args() {
-    // Regression test for a path resolution bug introduced with inner item handling.
     let (db, body, def) = lower(
         r#"
 //- minicore: fmt
@@ -221,3 +221,70 @@ fn main() {
         }"#]]
     .assert_eq(&body.pretty_print(&db, def))
 }
+
+#[test]
+fn test_macro_hygiene() {
+    let (db, body, def) = lower(
+        r##"
+//- minicore: fmt, from
+//- /main.rs
+mod error;
+
+use crate::error::error;
+
+fn main() {
+    // _ = forces body expansion instead of block def map expansion
+    _ = error!("Failed to resolve path `{}`", node.text());
+}
+//- /error.rs
+macro_rules! _error {
+    ($fmt:expr, $($arg:tt)+) => {$crate::error::intermediate!(format_args!($fmt, $($arg)+))}
+}
+pub(crate) use _error as error;
+macro_rules! _intermediate {
+    ($arg:expr) => {$crate::error::SsrError::new($arg)}
+}
+pub(crate) use _intermediate as intermediate;
+
+pub struct SsrError(pub(crate) core::fmt::Arguments);
+
+impl SsrError {
+    pub(crate) fn new(message: impl Into<core::fmt::Arguments>) -> SsrError {
+        SsrError(message.into())
+    }
+}
+"##,
+    );
+    println!("{}", db.dump_syntax_contexts());
+
+    assert_eq!(db.body_with_source_map(def.into()).1.diagnostics(), &[]);
+    expect![[r#"
+        fn main() {
+            _ = $crate::error::SsrError::new(
+                builtin#lang(Arguments::new_v1_formatted)(
+                    &[
+                        "\"Failed to resolve path `", "`\"",
+                    ],
+                    &[
+                        builtin#lang(Argument::new_display)(
+                            &node.text(),
+                        ),
+                    ],
+                    &[
+                        builtin#lang(Placeholder::new)(
+                            0usize,
+                            ' ',
+                            builtin#lang(Alignment::Unknown),
+                            0u32,
+                            builtin#lang(Count::Implied),
+                            builtin#lang(Count::Implied),
+                        ),
+                    ],
+                    unsafe {
+                        builtin#lang(UnsafeArg::new)()
+                    },
+                ),
+            );
+        }"#]]
+    .assert_eq(&body.pretty_print(&db, def))
+}
diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs
index 2af4622a072..635d13f24ad 100644
--- a/crates/hir-def/src/data.rs
+++ b/crates/hir-def/src/data.rs
@@ -794,7 +794,7 @@ impl<'a> AssocItemCollector<'a> {
 
         self.collect(&item_tree, tree_id, &iter);
 
-        self.expander.exit(self.db, mark);
+        self.expander.exit(mark);
     }
 }
 
diff --git a/crates/hir-def/src/expander.rs b/crates/hir-def/src/expander.rs
index e36aa19b8dd..398f116d831 100644
--- a/crates/hir-def/src/expander.rs
+++ b/crates/hir-def/src/expander.rs
@@ -94,8 +94,8 @@ impl Expander {
         ExpandResult { value: Some(InFile::new(macro_file.into(), value.0)), err: error.or(err) }
     }
 
-    pub fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) {
-        self.span_map = db.span_map(mark.file_id);
+    pub fn exit(&mut self, mut mark: Mark) {
+        self.span_map = mark.span_map;
         self.current_file_id = mark.file_id;
         if self.recursion_depth == u32::MAX {
             // Recursion limit has been reached somewhere in the macro expansion tree. Reset the
@@ -174,10 +174,11 @@ impl Expander {
                     let parse = value.cast::<T>()?;
 
                     self.recursion_depth += 1;
-                    self.span_map = db.span_map(file_id);
+                    let old_span_map = std::mem::replace(&mut self.span_map, db.span_map(file_id));
                     let old_file_id = std::mem::replace(&mut self.current_file_id, file_id);
                     let mark = Mark {
                         file_id: old_file_id,
+                        span_map: old_span_map,
                         bomb: DropBomb::new("expansion mark dropped"),
                     };
                     Some((mark, parse))
@@ -190,5 +191,6 @@ impl Expander {
 #[derive(Debug)]
 pub struct Mark {
     file_id: HirFileId,
+    span_map: SpanMap,
     bomb: DropBomb,
 }
diff --git a/crates/hir-def/src/generics.rs b/crates/hir-def/src/generics.rs
index 6d656bf9482..1c1c481a8ee 100644
--- a/crates/hir-def/src/generics.rs
+++ b/crates/hir-def/src/generics.rs
@@ -439,7 +439,7 @@ impl GenericParams {
                     let ctx = expander.ctx(db);
                     let type_ref = TypeRef::from_ast(&ctx, expanded.tree());
                     self.fill_implicit_impl_trait_args(db, &mut *exp, &type_ref);
-                    exp.1.exit(db, mark);
+                    exp.1.exit(mark);
                 }
             }
         });
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe.rs b/crates/hir-def/src/macro_expansion_tests/mbe.rs
index c4d44eab66c..9bf2a50d57c 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe.rs
@@ -997,9 +997,9 @@ macro_rules! vec {
 fn f() {
      {
         let mut v = Vec::new();
-        v.push((1));
-        v.push((2));
-        v.push((3));
+        v.push(1);
+        v.push(2);
+        v.push(3);
         v
     };
 }
@@ -1468,8 +1468,8 @@ macro_rules! matches {
     };
 }
 fn main() {
-    match (0) {
-        0|1 if (true )=>true , _=>false
+    match 0 {
+        0|1 if true =>true , _=>false
     };
 }
  "#]],
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs b/crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs
index dd83e5c04d4..967b5ad36ba 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs
@@ -62,10 +62,10 @@ macro_rules !implement_methods {
 struct Foo;
 impl Foo {
     fn alpha() -> &'static[u32] {
-        &[(1), (2), (3)]
+        &[1, 2, 3]
     }
     fn beta() -> &'static[u32] {
-        &[(1), (2), (3)]
+        &[1, 2, 3]
     }
 }
 "#]],
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
index 71dbb400b54..2886b2a366c 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
@@ -39,8 +39,8 @@ fn main() {
     };
      {
         let mut v = Vec::new();
-        v.push((1u32));
-        v.push((2));
+        v.push(1u32);
+        v.push(2);
         v
     };
 }
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs b/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
index b2ac7eb4094..ae56934f632 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
@@ -192,9 +192,9 @@ macro_rules! constant {
     ($e:expr ;) => {$e};
 }
 
-const _: () = (0.0);
-const _: () = (0.);
-const _: () = (0e0);
+const _: () = 0.0;
+const _: () = 0.;
+const _: () = 0e0;
 "#]],
     );
 }
diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs
index 00755b16e9f..d2c6559b06b 100644
--- a/crates/hir-expand/src/db.rs
+++ b/crates/hir-expand/src/db.rs
@@ -1,6 +1,10 @@
 //! Defines database & queries for macro expansion.
 
-use base_db::{salsa, span::SyntaxContextId, CrateId, Edition, FileId, SourceDatabase};
+use base_db::{
+    salsa::{self, debug::DebugQueryTable},
+    span::SyntaxContextId,
+    CrateId, Edition, FileId, SourceDatabase,
+};
 use either::Either;
 use limit::Limit;
 use mbe::{syntax_node_to_token_tree, ValueResult};
@@ -17,7 +21,7 @@ use crate::{
     builtin_attr_macro::pseudo_derive_attr_expansion,
     builtin_fn_macro::EagerExpander,
     fixup::{self, SyntaxFixupUndoInfo},
-    hygiene::{self, SyntaxContextData, Transparency},
+    hygiene::{apply_mark, SyntaxContextData, Transparency},
     span::{RealSpanMap, SpanMap, SpanMapRef},
     tt, AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallInfo,
     ExpandError, ExpandResult, ExpandTo, ExpansionSpanMap, HirFileId, HirFileIdRepr, MacroCallId,
@@ -53,7 +57,7 @@ impl DeclarativeMacroExpander {
             ),
             None => self
                 .mac
-                .expand(&tt, |s| s.ctx = db.apply_mark(s.ctx, call_id, self.transparency))
+                .expand(&tt, |s| s.ctx = apply_mark(db, s.ctx, call_id, self.transparency))
                 .map_err(Into::into),
         }
     }
@@ -115,16 +119,11 @@ pub trait ExpandDatabase: SourceDatabase {
     fn intern_macro_call(&self, macro_call: MacroCallLoc) -> MacroCallId;
     #[salsa::interned]
     fn intern_syntax_context(&self, ctx: SyntaxContextData) -> SyntaxContextId;
+
     #[salsa::transparent]
     fn setup_syntax_context_root(&self) -> ();
     #[salsa::transparent]
-    #[salsa::invoke(hygiene::apply_mark)]
-    fn apply_mark(
-        &self,
-        ctxt: SyntaxContextId,
-        call_id: MacroCallId,
-        transparency: hygiene::Transparency,
-    ) -> SyntaxContextId;
+    fn dump_syntax_contexts(&self) -> String;
 
     /// Lowers syntactic macro call to a token tree representation. That's a firewall
     /// query, only typing in the macro call itself changes the returned
@@ -269,7 +268,8 @@ pub fn expand_speculative(
         MacroDefKind::BuiltInAttr(it, _) => it.expand(db, actual_macro_call, &tt),
     };
 
-    let expand_to = macro_expand_to(db, actual_macro_call);
+    let expand_to = loc.expand_to();
+
     fixup::reverse_fixups(&mut speculative_expansion.value, &undo_info);
     let (node, rev_tmap) = token_tree_to_syntax_node(&speculative_expansion.value, expand_to);
 
@@ -318,12 +318,9 @@ fn parse_macro_expansion(
     macro_file: MacroFileId,
 ) -> ExpandResult<(Parse<SyntaxNode>, Arc<ExpansionSpanMap>)> {
     let _p = profile::span("parse_macro_expansion");
-    let mbe::ValueResult { value: tt, err } = macro_expand(db, macro_file.macro_call_id);
-
-    let expand_to = macro_expand_to(db, macro_file.macro_call_id);
-
-    tracing::debug!("expanded = {}", tt.as_debug_string());
-    tracing::debug!("kind = {:?}", expand_to);
+    let loc = db.lookup_intern_macro_call(macro_file.macro_call_id);
+    let expand_to = loc.expand_to();
+    let mbe::ValueResult { value: tt, err } = macro_expand(db, macro_file.macro_call_id, loc);
 
     let (parse, rev_token_map) = token_tree_to_syntax_node(&tt, expand_to);
 
@@ -575,9 +572,9 @@ fn macro_expander(db: &dyn ExpandDatabase, id: MacroDefId) -> TokenExpander {
 fn macro_expand(
     db: &dyn ExpandDatabase,
     macro_call_id: MacroCallId,
+    loc: MacroCallLoc,
 ) -> ExpandResult<Arc<tt::Subtree>> {
     let _p = profile::span("macro_expand");
-    let loc = db.lookup_intern_macro_call(macro_call_id);
 
     let ExpandResult { value: tt, mut err } = match loc.def.kind {
         MacroDefKind::ProcMacro(..) => return db.expand_proc_macro(macro_call_id),
@@ -711,10 +708,6 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<A
     ExpandResult { value: Arc::new(tt), err }
 }
 
-fn macro_expand_to(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandTo {
-    db.lookup_intern_macro_call(id).expand_to()
-}
-
 fn token_tree_to_syntax_node(
     tt: &tt::Subtree,
     expand_to: ExpandTo,
@@ -751,3 +744,40 @@ fn check_tt_count(tt: &tt::Subtree) -> Result<(), ExpandResult<Arc<tt::Subtree>>
 fn setup_syntax_context_root(db: &dyn ExpandDatabase) {
     db.intern_syntax_context(SyntaxContextData::root());
 }
+
+fn dump_syntax_contexts(db: &dyn ExpandDatabase) -> String {
+    let mut s = String::from("Expansions:");
+    let mut entries = InternMacroCallLookupQuery.in_db(db).entries::<Vec<_>>();
+    entries.sort_by_key(|e| e.key);
+    for e in entries {
+        let id = e.key;
+        let expn_data = e.value.as_ref().unwrap();
+        s.push_str(&format!(
+            "\n{:?}: parent: {:?}, call_site_ctxt: {:?}, def_site_ctxt: {:?}, kind: {:?}",
+            id,
+            expn_data.kind.file_id(),
+            expn_data.call_site,
+            SyntaxContextId::ROOT, // FIXME expn_data.def_site,
+            expn_data.kind.descr(),
+        ));
+    }
+
+    s.push_str("\n\nSyntaxContexts:\n");
+    let mut entries = InternSyntaxContextLookupQuery.in_db(db).entries::<Vec<_>>();
+    entries.sort_by_key(|e| e.key);
+    for e in entries {
+        struct SyntaxContextDebug<'a>(
+            &'a dyn ExpandDatabase,
+            SyntaxContextId,
+            &'a SyntaxContextData,
+        );
+
+        impl<'a> std::fmt::Debug for SyntaxContextDebug<'a> {
+            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+                self.2.fancy_debug(self.1, self.0, f)
+            }
+        }
+        stdx::format_to!(s, "{:?}\n", SyntaxContextDebug(db, e.key, &e.value.unwrap()));
+    }
+    s
+}
diff --git a/crates/hir-expand/src/hygiene.rs b/crates/hir-expand/src/hygiene.rs
index 8fdfa8af0ca..a809e92d622 100644
--- a/crates/hir-expand/src/hygiene.rs
+++ b/crates/hir-expand/src/hygiene.rs
@@ -8,7 +8,7 @@ use base_db::span::{MacroCallId, SpanData, SyntaxContextId};
 
 use crate::db::ExpandDatabase;
 
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Hash, PartialEq, Eq)]
 pub struct SyntaxContextData {
     pub outer_expn: Option<MacroCallId>,
     pub outer_transparency: Transparency,
@@ -19,6 +19,18 @@ pub struct SyntaxContextData {
     pub opaque_and_semitransparent: SyntaxContextId,
 }
 
+impl std::fmt::Debug for SyntaxContextData {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("SyntaxContextData")
+            .field("outer_expn", &self.outer_expn)
+            .field("outer_transparency", &self.outer_transparency)
+            .field("parent", &self.parent)
+            .field("opaque", &self.opaque)
+            .field("opaque_and_semitransparent", &self.opaque_and_semitransparent)
+            .finish()
+    }
+}
+
 impl SyntaxContextData {
     pub fn root() -> Self {
         SyntaxContextData {
@@ -29,6 +41,22 @@ impl SyntaxContextData {
             opaque_and_semitransparent: SyntaxContextId::ROOT,
         }
     }
+
+    pub fn fancy_debug(
+        self,
+        self_id: SyntaxContextId,
+        db: &dyn ExpandDatabase,
+        f: &mut std::fmt::Formatter<'_>,
+    ) -> std::fmt::Result {
+        write!(f, "#{self_id} parent: #{}, outer_mark: (", self.parent)?;
+        match self.outer_expn {
+            Some(id) => {
+                write!(f, "{:?}::{{{{expn{:?}}}}}", db.lookup_intern_macro_call(id).krate, id)?
+            }
+            None => write!(f, "root")?,
+        }
+        write!(f, ", {:?})", self.outer_transparency)
+    }
 }
 
 /// A property of a macro expansion that determines how identifiers
@@ -80,7 +108,7 @@ fn span_with_ctxt_from_mark(
     expn_id: MacroCallId,
     transparency: Transparency,
 ) -> SpanData {
-    SpanData { ctx: db.apply_mark(SyntaxContextId::ROOT, expn_id, transparency), ..span }
+    SpanData { ctx: apply_mark(db, SyntaxContextId::ROOT, expn_id, transparency), ..span }
 }
 
 pub(super) fn apply_mark(
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index b5f5fdd22ee..d743f2adae5 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -122,6 +122,7 @@ pub struct MacroDefId {
     pub kind: MacroDefKind,
     pub local_inner: bool,
     pub allow_internal_unsafe: bool,
+    // pub def_site: SyntaxContextId,
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -463,6 +464,14 @@ impl MacroCallLoc {
 }
 
 impl MacroCallKind {
+    fn descr(&self) -> &'static str {
+        match self {
+            MacroCallKind::FnLike { .. } => "macro call",
+            MacroCallKind::Derive { .. } => "derive macro",
+            MacroCallKind::Attr { .. } => "attribute macro",
+        }
+    }
+
     /// Returns the file containing the macro invocation.
     fn file_id(&self) -> HirFileId {
         match *self {
diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs
index c6bbf2f6140..fcfe1a3b5cf 100644
--- a/crates/hir-ty/src/infer/path.rs
+++ b/crates/hir-ty/src/infer/path.rs
@@ -390,6 +390,7 @@ impl InferenceContext<'_> {
     }
 }
 
+#[derive(Debug)]
 enum ValuePathResolution {
     // It's awkward to wrap a single ID in two enums, but we need both and this saves fallible
     // conversion between them + `unwrap()`.
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 9f5b59b239a..5122021d6d2 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -407,11 +407,7 @@ impl<'a> TyLoweringContext<'a> {
                             drop(expander);
                             let ty = self.lower_ty(&type_ref);
 
-                            self.expander
-                                .borrow_mut()
-                                .as_mut()
-                                .unwrap()
-                                .exit(self.db.upcast(), mark);
+                            self.expander.borrow_mut().as_mut().unwrap().exit(mark);
                             Some(ty)
                         }
                         _ => {
diff --git a/crates/hir-ty/src/tests.rs b/crates/hir-ty/src/tests.rs
index 9f6c237583e..1446e83fa88 100644
--- a/crates/hir-ty/src/tests.rs
+++ b/crates/hir-ty/src/tests.rs
@@ -128,7 +128,6 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
             None => continue,
         };
         let def_map = module.def_map(&db);
-        dbg!(def_map.dump(&db));
         visit_module(&db, &def_map, module.local_id, &mut |it| defs.push(it));
     }
     defs.sort_by_key(|def| match def {
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs
index 5e1ceacf12c..012b02a3f87 100644
--- a/crates/mbe/src/expander/matcher.rs
+++ b/crates/mbe/src/expander/matcher.rs
@@ -792,9 +792,21 @@ fn match_meta_var<S: Span>(
                 }
                 _ => {}
             };
-            return input
-                .expect_fragment(parser::PrefixEntryPoint::Expr)
-                .map(|tt| tt.map(tt::TokenTree::subtree_or_wrap).map(Fragment::Expr));
+            return input.expect_fragment(parser::PrefixEntryPoint::Expr).map(|tt| {
+                tt.map(|tt| match tt {
+                    tt::TokenTree::Leaf(leaf) => tt::Subtree {
+                        delimiter: tt::Delimiter::dummy_invisible(),
+                        token_trees: vec![leaf.into()],
+                    },
+                    tt::TokenTree::Subtree(mut s) => {
+                        if s.delimiter.kind == tt::DelimiterKind::Invisible {
+                            s.delimiter.kind = tt::DelimiterKind::Parenthesis;
+                        }
+                        s
+                    }
+                })
+                .map(Fragment::Expr)
+            });
         }
         MetaVarKind::Ident | MetaVarKind::Tt | MetaVarKind::Lifetime | MetaVarKind::Literal => {
             let tt_result = match kind {
diff --git a/crates/mbe/src/expander/transcriber.rs b/crates/mbe/src/expander/transcriber.rs
index 40f683d8462..e4a46c16597 100644
--- a/crates/mbe/src/expander/transcriber.rs
+++ b/crates/mbe/src/expander/transcriber.rs
@@ -444,15 +444,8 @@ fn expand_repeat<S: Span>(
 fn push_fragment<S: Span>(buf: &mut Vec<tt::TokenTree<S>>, fragment: Fragment<S>) {
     match fragment {
         Fragment::Tokens(tt::TokenTree::Subtree(tt)) => push_subtree(buf, tt),
-        Fragment::Expr(mut tt) => {
-            if tt.delimiter.kind == tt::DelimiterKind::Invisible {
-                tt.delimiter = tt::Delimiter {
-                    open: S::DUMMY,
-                    close: S::DUMMY,
-                    kind: tt::DelimiterKind::Parenthesis,
-                };
-            }
-            buf.push(tt.into())
+        Fragment::Expr(sub) => {
+            push_subtree(buf, sub);
         }
         Fragment::Path(tt) => fix_up_and_push_path_tt(buf, tt),
         Fragment::Tokens(tt) => buf.push(tt),