about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <me@lukaswirth.dev>2025-06-05 07:25:14 +0200
committerLukas Wirth <me@lukaswirth.dev>2025-06-05 07:25:15 +0200
commit77b0d3e106b97e3e53783502c896d16876eefd0f (patch)
treedfc382a2ed181df821c5b387adce11bb63460907
parentfd269a0df6bc1290428b61c4d092e42a9a59a9e1 (diff)
downloadrust-77b0d3e106b97e3e53783502c896d16876eefd0f.tar.gz
rust-77b0d3e106b97e3e53783502c896d16876eefd0f.zip
Deduplicate code in proc-macro-srv
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs133
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs137
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs168
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs6
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs10
6 files changed, 160 insertions, 297 deletions
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs
index 11dbd920091..ad285990334 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs
@@ -10,6 +10,7 @@
 
 use std::fmt;
 
+use intern::Symbol;
 use proc_macro::bridge;
 
 mod token_stream;
@@ -112,3 +113,135 @@ fn literal_kind_to_internal(kind: bridge::LitKind) -> tt::LitKind {
         bridge::LitKind::ErrWithGuar => tt::LitKind::Err(()),
     }
 }
+
+pub(super) fn literal_from_str<Span: Copy>(
+    s: &str,
+    span: Span,
+) -> Result<bridge::Literal<Span, Symbol>, ()> {
+    use proc_macro::bridge::LitKind;
+    use rustc_lexer::{LiteralKind, Token, TokenKind};
+
+    let mut tokens = rustc_lexer::tokenize(s);
+    let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 });
+
+    let lit = if minus_or_lit.kind == TokenKind::Minus {
+        let lit = tokens.next().ok_or(())?;
+        if !matches!(
+            lit.kind,
+            TokenKind::Literal { kind: LiteralKind::Int { .. } | LiteralKind::Float { .. }, .. }
+        ) {
+            return Err(());
+        }
+        lit
+    } else {
+        minus_or_lit
+    };
+
+    if tokens.next().is_some() {
+        return Err(());
+    }
+
+    let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
+    let (kind, start_offset, end_offset) = match kind {
+        LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
+        LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
+        LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
+        LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
+        LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
+        LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
+        LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
+        LiteralKind::RawStr { n_hashes } => (
+            LitKind::StrRaw(n_hashes.unwrap_or_default()),
+            2 + n_hashes.unwrap_or_default() as usize,
+            1 + n_hashes.unwrap_or_default() as usize,
+        ),
+        LiteralKind::RawByteStr { n_hashes } => (
+            LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
+            3 + n_hashes.unwrap_or_default() as usize,
+            1 + n_hashes.unwrap_or_default() as usize,
+        ),
+        LiteralKind::RawCStr { n_hashes } => (
+            LitKind::CStrRaw(n_hashes.unwrap_or_default()),
+            3 + n_hashes.unwrap_or_default() as usize,
+            1 + n_hashes.unwrap_or_default() as usize,
+        ),
+    };
+
+    let (lit, suffix) = s.split_at(suffix_start as usize);
+    let lit = &lit[start_offset..lit.len() - end_offset];
+    let suffix = match suffix {
+        "" | "_" => None,
+        suffix => Some(Symbol::intern(suffix)),
+    };
+
+    Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span })
+}
+
+pub(super) fn from_token_tree<Span: Copy>(
+    tree: bridge::TokenTree<TokenStream<Span>, Span, Symbol>,
+) -> TokenStream<Span> {
+    match tree {
+        bridge::TokenTree::Group(group) => {
+            let group = TopSubtree::from_bridge(group);
+            TokenStream { token_trees: group.0 }
+        }
+
+        bridge::TokenTree::Ident(ident) => {
+            let text = ident.sym;
+            let ident: tt::Ident<Span> = tt::Ident {
+                sym: text,
+                span: ident.span,
+                is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No },
+            };
+            let leaf = tt::Leaf::from(ident);
+            let tree = tt::TokenTree::from(leaf);
+            TokenStream { token_trees: vec![tree] }
+        }
+
+        bridge::TokenTree::Literal(literal) => {
+            let token_trees =
+                if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
+                    let punct = tt::Punct {
+                        spacing: tt::Spacing::Alone,
+                        span: literal.span,
+                        char: '-' as char,
+                    };
+                    let leaf: tt::Leaf<Span> = tt::Leaf::from(punct);
+                    let minus_tree = tt::TokenTree::from(leaf);
+
+                    let literal = tt::Literal {
+                        symbol: Symbol::intern(symbol),
+                        suffix: literal.suffix,
+                        span: literal.span,
+                        kind: literal_kind_to_internal(literal.kind),
+                    };
+                    let leaf: tt::Leaf<Span> = tt::Leaf::from(literal);
+                    let tree = tt::TokenTree::from(leaf);
+                    vec![minus_tree, tree]
+                } else {
+                    let literal = tt::Literal {
+                        symbol: literal.symbol,
+                        suffix: literal.suffix,
+                        span: literal.span,
+                        kind: literal_kind_to_internal(literal.kind),
+                    };
+
+                    let leaf: tt::Leaf<Span> = tt::Leaf::from(literal);
+                    let tree = tt::TokenTree::from(leaf);
+                    vec![tree]
+                };
+            TokenStream { token_trees }
+        }
+
+        bridge::TokenTree::Punct(p) => {
+            let punct = tt::Punct {
+                char: p.ch as char,
+                spacing: if p.joint { tt::Spacing::Joint } else { tt::Spacing::Alone },
+                span: p.span,
+            };
+            let leaf = tt::Leaf::from(punct);
+            let tree = tt::TokenTree::from(leaf);
+            TokenStream { token_trees: vec![tree] }
+        }
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
index e0c6e68f803..5d1271ba81e 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
@@ -14,16 +14,7 @@ use proc_macro::bridge::{self, server};
 use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span};
 use tt::{TextRange, TextSize};
 
-use crate::server_impl::{TopSubtree, literal_kind_to_internal, token_stream::TokenStreamBuilder};
-mod tt {
-    pub use tt::*;
-
-    pub type TokenTree = ::tt::TokenTree<super::Span>;
-    pub type Leaf = ::tt::Leaf<super::Span>;
-    pub type Literal = ::tt::Literal<super::Span>;
-    pub type Punct = ::tt::Punct<super::Span>;
-    pub type Ident = ::tt::Ident<super::Span>;
-}
+use crate::server_impl::{from_token_tree, literal_from_str, token_stream::TokenStreamBuilder};
 
 type TokenStream = crate::server_impl::TokenStream<Span>;
 
@@ -62,66 +53,7 @@ impl server::FreeFunctions for RaSpanServer {
         &mut self,
         s: &str,
     ) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
-        use proc_macro::bridge::LitKind;
-        use rustc_lexer::{LiteralKind, Token, TokenKind};
-
-        let mut tokens = rustc_lexer::tokenize(s);
-        let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 });
-
-        let lit = if minus_or_lit.kind == TokenKind::Minus {
-            let lit = tokens.next().ok_or(())?;
-            if !matches!(
-                lit.kind,
-                TokenKind::Literal {
-                    kind: LiteralKind::Int { .. } | LiteralKind::Float { .. },
-                    ..
-                }
-            ) {
-                return Err(());
-            }
-            lit
-        } else {
-            minus_or_lit
-        };
-
-        if tokens.next().is_some() {
-            return Err(());
-        }
-
-        let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
-        let (kind, start_offset, end_offset) = match kind {
-            LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
-            LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
-            LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
-            LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
-            LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
-            LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
-            LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
-            LiteralKind::RawStr { n_hashes } => (
-                LitKind::StrRaw(n_hashes.unwrap_or_default()),
-                2 + n_hashes.unwrap_or_default() as usize,
-                1 + n_hashes.unwrap_or_default() as usize,
-            ),
-            LiteralKind::RawByteStr { n_hashes } => (
-                LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
-                3 + n_hashes.unwrap_or_default() as usize,
-                1 + n_hashes.unwrap_or_default() as usize,
-            ),
-            LiteralKind::RawCStr { n_hashes } => (
-                LitKind::CStrRaw(n_hashes.unwrap_or_default()),
-                3 + n_hashes.unwrap_or_default() as usize,
-                1 + n_hashes.unwrap_or_default() as usize,
-            ),
-        };
-
-        let (lit, suffix) = s.split_at(suffix_start as usize);
-        let lit = &lit[start_offset..lit.len() - end_offset];
-        let suffix = match suffix {
-            "" | "_" => None,
-            suffix => Some(Symbol::intern(suffix)),
-        };
-
-        Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span: self.call_site })
+        literal_from_str(s, self.call_site)
     }
 
     fn emit_diagnostic(&mut self, _: bridge::Diagnostic<Self::Span>) {
@@ -149,70 +81,7 @@ impl server::TokenStream for RaSpanServer {
         &mut self,
         tree: bridge::TokenTree<Self::TokenStream, Self::Span, Self::Symbol>,
     ) -> Self::TokenStream {
-        match tree {
-            bridge::TokenTree::Group(group) => {
-                let group = TopSubtree::from_bridge(group);
-                TokenStream { token_trees: group.0 }
-            }
-
-            bridge::TokenTree::Ident(ident) => {
-                let text = ident.sym;
-                let ident: tt::Ident = tt::Ident {
-                    sym: text,
-                    span: ident.span,
-                    is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No },
-                };
-                let leaf = tt::Leaf::from(ident);
-                let tree = tt::TokenTree::from(leaf);
-                TokenStream { token_trees: vec![tree] }
-            }
-
-            bridge::TokenTree::Literal(literal) => {
-                let token_trees =
-                    if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
-                        let punct = tt::Punct {
-                            spacing: tt::Spacing::Alone,
-                            span: literal.span,
-                            char: '-' as char,
-                        };
-                        let leaf: tt::Leaf = tt::Leaf::from(punct);
-                        let minus_tree = tt::TokenTree::from(leaf);
-
-                        let literal = tt::Literal {
-                            symbol: Symbol::intern(symbol),
-                            suffix: literal.suffix,
-                            span: literal.span,
-                            kind: literal_kind_to_internal(literal.kind),
-                        };
-                        let leaf: tt::Leaf = tt::Leaf::from(literal);
-                        let tree = tt::TokenTree::from(leaf);
-                        vec![minus_tree, tree]
-                    } else {
-                        let literal = tt::Literal {
-                            symbol: literal.symbol,
-                            suffix: literal.suffix,
-                            span: literal.span,
-                            kind: literal_kind_to_internal(literal.kind),
-                        };
-
-                        let leaf: tt::Leaf = tt::Leaf::from(literal);
-                        let tree = tt::TokenTree::from(leaf);
-                        vec![tree]
-                    };
-                TokenStream { token_trees }
-            }
-
-            bridge::TokenTree::Punct(p) => {
-                let punct = tt::Punct {
-                    char: p.ch as char,
-                    spacing: if p.joint { tt::Spacing::Joint } else { tt::Spacing::Alone },
-                    span: p.span,
-                };
-                let leaf = tt::Leaf::from(punct);
-                let tree = tt::TokenTree::from(leaf);
-                TokenStream { token_trees: vec![tree] }
-            }
-        }
+        from_token_tree(tree)
     }
 
     fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs
index d55b269f868..b493b325e83 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs
@@ -5,23 +5,9 @@ use std::ops::{Bound, Range};
 use intern::Symbol;
 use proc_macro::bridge::{self, server};
 
-use crate::server_impl::{TopSubtree, literal_kind_to_internal, token_stream::TokenStreamBuilder};
-mod tt {
-    pub use span::TokenId;
+use crate::server_impl::{from_token_tree, literal_from_str, token_stream::TokenStreamBuilder};
 
-    pub use tt::*;
-
-    pub type TokenTree = ::tt::TokenTree<TokenId>;
-    pub type Leaf = ::tt::Leaf<TokenId>;
-    pub type Literal = ::tt::Literal<TokenId>;
-    pub type Punct = ::tt::Punct<TokenId>;
-    pub type Ident = ::tt::Ident<TokenId>;
-}
-type TokenTree = tt::TokenTree;
-type Punct = tt::Punct;
-type Spacing = tt::Spacing;
-type Literal = tt::Literal;
-type Span = tt::TokenId;
+type Span = span::TokenId;
 type TokenStream = crate::server_impl::TokenStream<Span>;
 
 pub struct FreeFunctions;
@@ -49,67 +35,7 @@ impl server::FreeFunctions for TokenIdServer {
         &mut self,
         s: &str,
     ) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
-        use proc_macro::bridge::LitKind;
-        use rustc_lexer::{LiteralKind, Token, TokenKind};
-
-        let mut tokens = rustc_lexer::tokenize(s);
-        let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 });
-
-        let lit = if minus_or_lit.kind == TokenKind::Minus {
-            let lit = tokens.next().ok_or(())?;
-            if !matches!(
-                lit.kind,
-                TokenKind::Literal {
-                    kind: LiteralKind::Int { .. } | LiteralKind::Float { .. },
-                    ..
-                }
-            ) {
-                return Err(());
-            }
-            lit
-        } else {
-            minus_or_lit
-        };
-
-        if tokens.next().is_some() {
-            return Err(());
-        }
-
-        let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) };
-
-        let (kind, start_offset, end_offset) = match kind {
-            LiteralKind::Int { .. } => (LitKind::Integer, 0, 0),
-            LiteralKind::Float { .. } => (LitKind::Float, 0, 0),
-            LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize),
-            LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize),
-            LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize),
-            LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize),
-            LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize),
-            LiteralKind::RawStr { n_hashes } => (
-                LitKind::StrRaw(n_hashes.unwrap_or_default()),
-                2 + n_hashes.unwrap_or_default() as usize,
-                1 + n_hashes.unwrap_or_default() as usize,
-            ),
-            LiteralKind::RawByteStr { n_hashes } => (
-                LitKind::ByteStrRaw(n_hashes.unwrap_or_default()),
-                3 + n_hashes.unwrap_or_default() as usize,
-                1 + n_hashes.unwrap_or_default() as usize,
-            ),
-            LiteralKind::RawCStr { n_hashes } => (
-                LitKind::CStrRaw(n_hashes.unwrap_or_default()),
-                3 + n_hashes.unwrap_or_default() as usize,
-                1 + n_hashes.unwrap_or_default() as usize,
-            ),
-        };
-
-        let (lit, suffix) = s.split_at(suffix_start as usize);
-        let lit = &lit[start_offset..lit.len() - end_offset];
-        let suffix = match suffix {
-            "" | "_" => None,
-            suffix => Some(Symbol::intern(suffix)),
-        };
-
-        Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span: self.call_site })
+        literal_from_str(s, self.call_site)
     }
 
     fn emit_diagnostic(&mut self, _: bridge::Diagnostic<Self::Span>) {}
@@ -135,69 +61,7 @@ impl server::TokenStream for TokenIdServer {
         &mut self,
         tree: bridge::TokenTree<Self::TokenStream, Self::Span, Self::Symbol>,
     ) -> Self::TokenStream {
-        match tree {
-            bridge::TokenTree::Group(group) => {
-                let group = TopSubtree::from_bridge(group);
-                TokenStream { token_trees: group.0 }
-            }
-
-            bridge::TokenTree::Ident(ident) => {
-                let ident: tt::Ident = tt::Ident {
-                    sym: ident.sym,
-                    span: ident.span,
-                    is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No },
-                };
-                let leaf = tt::Leaf::from(ident);
-                let tree = TokenTree::from(leaf);
-                TokenStream { token_trees: vec![tree] }
-            }
-
-            bridge::TokenTree::Literal(literal) => {
-                let token_trees =
-                    if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
-                        let punct = tt::Punct {
-                            spacing: tt::Spacing::Alone,
-                            span: literal.span,
-                            char: '-' as char,
-                        };
-                        let leaf: tt::Leaf = tt::Leaf::from(punct);
-                        let minus_tree = tt::TokenTree::from(leaf);
-
-                        let literal = Literal {
-                            symbol: Symbol::intern(symbol),
-                            suffix: literal.suffix,
-                            span: literal.span,
-                            kind: literal_kind_to_internal(literal.kind),
-                        };
-                        let leaf: tt::Leaf = tt::Leaf::from(literal);
-                        let tree = tt::TokenTree::from(leaf);
-                        vec![minus_tree, tree]
-                    } else {
-                        let literal = Literal {
-                            symbol: literal.symbol,
-                            suffix: literal.suffix,
-                            span: literal.span,
-                            kind: literal_kind_to_internal(literal.kind),
-                        };
-
-                        let leaf: tt::Leaf = tt::Leaf::from(literal);
-                        let tree = tt::TokenTree::from(leaf);
-                        vec![tree]
-                    };
-                TokenStream { token_trees }
-            }
-
-            bridge::TokenTree::Punct(p) => {
-                let punct = Punct {
-                    char: p.ch as char,
-                    spacing: if p.joint { Spacing::Joint } else { Spacing::Alone },
-                    span: p.span,
-                };
-                let leaf = tt::Leaf::from(punct);
-                let tree = TokenTree::from(leaf);
-                TokenStream { token_trees: vec![tree] }
-            }
-        }
+        from_token_tree(tree)
     }
 
     fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
@@ -337,6 +201,8 @@ impl server::Server for TokenIdServer {
 
 #[cfg(test)]
 mod tests {
+    use span::TokenId;
+
     use super::*;
 
     #[test]
@@ -345,18 +211,18 @@ mod tests {
             token_trees: vec![
                 tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                     sym: Symbol::intern("struct"),
-                    span: tt::TokenId(0),
+                    span: TokenId(0),
                     is_raw: tt::IdentIsRaw::No,
                 })),
                 tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                     sym: Symbol::intern("T"),
-                    span: tt::TokenId(0),
+                    span: TokenId(0),
                     is_raw: tt::IdentIsRaw::No,
                 })),
                 tt::TokenTree::Subtree(tt::Subtree {
                     delimiter: tt::Delimiter {
-                        open: tt::TokenId(0),
-                        close: tt::TokenId(0),
+                        open: TokenId(0),
+                        close: TokenId(0),
                         kind: tt::DelimiterKind::Brace,
                     },
                     len: 0,
@@ -372,8 +238,8 @@ mod tests {
         let subtree_paren_a = vec![
             tt::TokenTree::Subtree(tt::Subtree {
                 delimiter: tt::Delimiter {
-                    open: tt::TokenId(0),
-                    close: tt::TokenId(0),
+                    open: TokenId(0),
+                    close: TokenId(0),
                     kind: tt::DelimiterKind::Parenthesis,
                 },
                 len: 1,
@@ -381,24 +247,24 @@ mod tests {
             tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                 is_raw: tt::IdentIsRaw::No,
                 sym: Symbol::intern("a"),
-                span: tt::TokenId(0),
+                span: TokenId(0),
             })),
         ];
 
-        let t1 = TokenStream::from_str("(a)", tt::TokenId(0)).unwrap();
+        let t1 = TokenStream::from_str("(a)", TokenId(0)).unwrap();
         assert_eq!(t1.token_trees.len(), 2);
         assert!(t1.token_trees[0..2] == subtree_paren_a);
 
-        let t2 = TokenStream::from_str("(a);", tt::TokenId(0)).unwrap();
+        let t2 = TokenStream::from_str("(a);", TokenId(0)).unwrap();
         assert_eq!(t2.token_trees.len(), 3);
         assert!(t2.token_trees[0..2] == subtree_paren_a);
 
-        let underscore = TokenStream::from_str("_", tt::TokenId(0)).unwrap();
+        let underscore = TokenStream::from_str("_", TokenId(0)).unwrap();
         assert!(
             underscore.token_trees[0]
                 == tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                     sym: Symbol::intern("_"),
-                    span: tt::TokenId(0),
+                    span: TokenId(0),
                     is_raw: tt::IdentIsRaw::No,
                 }))
         );
diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
index 6e730b1aea2..bb02284a513 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
@@ -431,12 +431,6 @@ impl CargoWorkspace {
                 .ok_or(cargo_metadata::Error::NoJson)?;
             Ok((cargo_metadata::MetadataCommand::parse(stdout)?, None))
         })()
-        .map(|(metadata, error)| {
-            (
-                metadata,
-                error.map(|e| e.context(format!("Failed to run `{:?}`", meta.cargo_command()))),
-            )
-        })
         .with_context(|| format!("Failed to run `{:?}`", meta.cargo_command()))
     }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs
index 673eaa5952f..5bea7084fdb 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs
@@ -108,8 +108,7 @@ impl GlobalState {
     /// edge users from being upset!
     pub(crate) fn poke_rust_analyzer_developer(&mut self, message: String) {
         let from_source_build = option_env!("POKE_RA_DEVS").is_some();
-        let profiling_enabled = std::env::var("RA_PROFILE").is_ok();
-        if from_source_build || profiling_enabled {
+        if from_source_build {
             self.show_and_log_error(message, None);
         }
     }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
index f6bcb5642c3..59073af983b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
@@ -975,10 +975,6 @@ version = \"0.0.0\"
 }
 
 fn out_dirs_check_impl(root_contains_symlink: bool) {
-    if skip_slow_tests() {
-        return;
-    }
-
     let mut server = Project::with_fixture(
         r###"
 //- /Cargo.toml
@@ -1130,12 +1126,18 @@ fn main() {
 
 #[test]
 fn out_dirs_check() {
+    if skip_slow_tests() {
+        return;
+    }
     out_dirs_check_impl(false);
 }
 
 #[test]
 #[cfg(not(windows))] // windows requires elevated permissions to create symlinks
 fn root_contains_symlink_out_dirs_check() {
+    if skip_slow_tests() {
+        return;
+    }
     out_dirs_check_impl(true);
 }