Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #153217 - JonathanBrouwer:rollup-iXVG70B, r=JonathanBrouwer
Rollup of 12 pull requests Successful merges: - rust-lang/rust#153211 (`rust-analyzer` subtree update) - rust-lang/rust#149027 (Improve cross-crate trait impl param mismatch suggestions ) - rust-lang/rust#152730 (add field representing types) - rust-lang/rust#153136 (Correctly handle `#[doc(alias = "...")]` attribute on inlined reexports) - rust-lang/rust#152165 (Normalize capture place `ty`s to prevent ICE) - rust-lang/rust#152615 (refactor 'valid for read/write' definition: exclude null) - rust-lang/rust#153109 (Fix LegacyKeyValueFormat report from docker build: aarch64-gnu-debug) - rust-lang/rust#153172 (Fix comment about placeholders) - rust-lang/rust#153187 (Fix ICE when macro-expanded extern crate shadows std) - rust-lang/rust#153190 (Don't allow subdiagnostic to use variables from their parent) - rust-lang/rust#153200 (Remove redundant clone) - rust-lang/rust#153216 (mark two polonius tests as known-bug)
bors 7 weeks ago
parent 918061f · parent 1761ae0 · commit b32496f
-rw-r--r--crates/hir-ty/src/infer/cast.rs6
-rw-r--r--crates/ide-assists/src/handlers/fix_visibility.rs43
-rw-r--r--crates/ide-assists/src/handlers/generate_derive.rs19
-rw-r--r--crates/ide-assists/src/handlers/replace_if_let_with_match.rs74
-rw-r--r--crates/ide-completion/src/completions/pattern.rs2
-rw-r--r--crates/ide-completion/src/tests/pattern.rs32
-rw-r--r--crates/ide-completion/src/tests/record.rs6
-rw-r--r--crates/ide-diagnostics/src/handlers/invalid_cast.rs2
-rw-r--r--crates/load-cargo/src/lib.rs40
-rw-r--r--crates/proc-macro-api/src/bidirectional_protocol/msg.rs13
-rw-r--r--crates/proc-macro-srv-cli/src/main_loop.rs34
-rw-r--r--crates/proc-macro-srv/src/lib.rs1
-rw-r--r--crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs6
-rw-r--r--crates/proc-macro-srv/src/tests/utils.rs4
-rw-r--r--crates/project-model/src/cargo_config_file.rs17
-rw-r--r--crates/rust-analyzer/src/handlers/dispatch.rs3
-rw-r--r--crates/rust-analyzer/tests/slow-tests/main.rs12
-rw-r--r--crates/syntax/src/ast/syntax_factory/constructors.rs6
18 files changed, 255 insertions, 65 deletions
diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs
index d69b00adb7..fc38361d7e 100644
--- a/crates/hir-ty/src/infer/cast.rs
+++ b/crates/hir-ty/src/infer/cast.rs
@@ -328,11 +328,7 @@ impl<'db> CastCheck<'db> {
//
// Note that trait upcasting goes through a different mechanism (`coerce_unsized`)
// and is unaffected by this check.
- (Some(src_principal), Some(dst_principal)) => {
- if src_principal == dst_principal {
- return Ok(());
- }
-
+ (Some(src_principal), Some(_)) => {
// We need to reconstruct trait object types.
// `m_src` and `m_dst` won't work for us here because they will potentially
// contain wrappers, which we do not care about.
diff --git a/crates/ide-assists/src/handlers/fix_visibility.rs b/crates/ide-assists/src/handlers/fix_visibility.rs
index 0fd8057a39..5134b98f1b 100644
--- a/crates/ide-assists/src/handlers/fix_visibility.rs
+++ b/crates/ide-assists/src/handlers/fix_visibility.rs
@@ -2,7 +2,7 @@ use hir::{HasSource, HasVisibility, ModuleDef, PathResolution, ScopeDef, db::Hir
use ide_db::FileId;
use syntax::{
AstNode, TextRange,
- ast::{self, HasVisibility as _, edit_in_place::HasVisibilityEdit, make},
+ ast::{self, HasVisibility as _, syntax_factory::SyntaxFactory},
};
use crate::{AssistContext, AssistId, Assists};
@@ -59,10 +59,12 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
let (vis_owner, target, target_file, target_name) = target_data_for_def(ctx.db(), def)?;
+ let make = SyntaxFactory::without_mappings();
+
let missing_visibility = if current_module.krate(ctx.db()) == target_module.krate(ctx.db()) {
- make::visibility_pub_crate()
+ make.visibility_pub_crate()
} else {
- make::visibility_pub()
+ make.visibility_pub()
};
let assist_label = match target_name {
@@ -75,15 +77,36 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
}
};
- acc.add(AssistId::quick_fix("fix_visibility"), assist_label, target, |edit| {
- edit.edit_file(target_file);
-
- let vis_owner = edit.make_mut(vis_owner);
- vis_owner.set_visibility(Some(missing_visibility.clone_for_update()));
+ acc.add(AssistId::quick_fix("fix_visibility"), assist_label, target, |builder| {
+ let mut editor = builder.make_editor(vis_owner.syntax());
+
+ if let Some(current_visibility) = vis_owner.visibility() {
+ editor.replace(current_visibility.syntax(), missing_visibility.syntax());
+ } else {
+ let vis_before = vis_owner
+ .syntax()
+ .children_with_tokens()
+ .find(|it| {
+ !matches!(
+ it.kind(),
+ syntax::SyntaxKind::WHITESPACE
+ | syntax::SyntaxKind::COMMENT
+ | syntax::SyntaxKind::ATTR
+ )
+ })
+ .unwrap_or_else(|| vis_owner.syntax().first_child_or_token().unwrap());
+
+ editor.insert_all(
+ syntax::syntax_editor::Position::before(vis_before),
+ vec![missing_visibility.syntax().clone().into(), make.whitespace(" ").into()],
+ );
+ }
- if let Some((cap, vis)) = ctx.config.snippet_cap.zip(vis_owner.visibility()) {
- edit.add_tabstop_before(cap, vis);
+ if let Some(cap) = ctx.config.snippet_cap {
+ editor.add_annotation(missing_visibility.syntax(), builder.make_tabstop_before(cap));
}
+
+ builder.add_file_edits(target_file, editor);
})
}
diff --git a/crates/ide-assists/src/handlers/generate_derive.rs b/crates/ide-assists/src/handlers/generate_derive.rs
index 06fef4af22..3ef68f06e4 100644
--- a/crates/ide-assists/src/handlers/generate_derive.rs
+++ b/crates/ide-assists/src/handlers/generate_derive.rs
@@ -1,7 +1,7 @@
use syntax::{
SyntaxKind::{ATTR, COMMENT, WHITESPACE},
T,
- ast::{self, AstNode, HasAttrs, edit::IndentLevel, make},
+ ast::{self, AstNode, HasAttrs, edit::IndentLevel, syntax_factory::SyntaxFactory},
syntax_editor::{Element, Position},
};
@@ -42,13 +42,15 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
};
acc.add(AssistId::generate("generate_derive"), "Add `#[derive]`", target, |edit| {
+ let make = SyntaxFactory::without_mappings();
+
match derive_attr {
None => {
- let derive = make::attr_outer(make::meta_token_tree(
- make::ext::ident_path("derive"),
- make::token_tree(T!['('], vec![]).clone_for_update(),
- ))
- .clone_for_update();
+ let derive =
+ make.attr_outer(make.meta_token_tree(
+ make.ident_path("derive"),
+ make.token_tree(T!['('], vec![]),
+ ));
let mut editor = edit.make_editor(nominal.syntax());
let indent = IndentLevel::from_node(nominal.syntax());
@@ -57,11 +59,12 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
.children_with_tokens()
.find(|it| !matches!(it.kind(), WHITESPACE | COMMENT | ATTR))
.map_or(Position::first_child_of(nominal.syntax()), Position::before);
+
editor.insert_all(
after_attrs_and_comments,
vec![
derive.syntax().syntax_element(),
- make::tokens::whitespace(&format!("\n{indent}")).syntax_element(),
+ make.whitespace(&format!("\n{indent}")).syntax_element(),
],
);
@@ -72,7 +75,9 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
.expect("failed to get token tree out of Meta")
.r_paren_token()
.expect("make::attr_outer was expected to have a R_PAREN");
+
let tabstop_before = edit.make_tabstop_before(cap);
+
editor.add_annotation(delimiter, tabstop_before);
edit.add_file_edits(ctx.vfs_file_id(), editor);
}
diff --git a/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs
index d2452f28c4..dcadb5368d 100644
--- a/crates/ide-assists/src/handlers/replace_if_let_with_match.rs
+++ b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs
@@ -57,7 +57,7 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<'
let if_exprs = successors(Some(if_expr.clone()), |expr| match expr.else_branch()? {
ast::ElseBranch::IfExpr(expr) => Some(expr),
ast::ElseBranch::Block(block) => {
- let block = unwrap_trivial_block(block).clone_for_update();
+ let block = unwrap_trivial_block(block);
else_block = Some(block.reset_indent().indent(IndentLevel(1)));
None
}
@@ -91,7 +91,7 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<'
guard
};
- let body = if_expr.then_branch()?.clone_for_update().indent(IndentLevel(1));
+ let body = if_expr.then_branch()?.indent(IndentLevel(1));
cond_bodies.push((cond, guard, body));
}
@@ -114,7 +114,7 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<'
let make_match_arm =
|(pat, guard, body): (_, Option<ast::Expr>, ast::BlockExpr)| {
// Dedent from original position, then indent for match arm
- let body = body.dedent(indent).indent(IndentLevel::single());
+ let body = body.dedent(indent);
let body = unwrap_trivial_block(body);
match (pat, guard.map(|it| make.match_guard(it))) {
(Some(pat), guard) => make.match_arm(pat, guard, body),
@@ -127,8 +127,8 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext<'
}
};
let arms = cond_bodies.into_iter().map(make_match_arm).chain([else_arm]);
- let match_expr =
- make.expr_match(scrutinee_to_be_expr, make.match_arm_list(arms)).indent(indent);
+ let expr = scrutinee_to_be_expr.reset_indent();
+ let match_expr = make.expr_match(expr, make.match_arm_list(arms)).indent(indent);
match_expr.into()
};
@@ -246,7 +246,7 @@ pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext<'
first_arm.guard(),
second_arm.guard(),
)?;
- let scrutinee = match_expr.expr()?;
+ let scrutinee = match_expr.expr()?.reset_indent();
let guard = guard.and_then(|it| it.condition());
let let_ = match &if_let_pat {
@@ -293,10 +293,8 @@ pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext<'
} else {
condition
};
- let then_expr =
- then_expr.clone_for_update().reset_indent().indent(IndentLevel::single());
- let else_expr =
- else_expr.clone_for_update().reset_indent().indent(IndentLevel::single());
+ let then_expr = then_expr.reset_indent();
+ let else_expr = else_expr.reset_indent();
let then_block = make_block_expr(then_expr);
let else_expr = if is_empty_expr(&else_expr) { None } else { Some(else_expr) };
let if_let_expr = make
@@ -956,7 +954,9 @@ fn foo(x: Result<i32, ()>) {
r#"
fn main() {
if true {
- $0if let Ok(rel_path) = path.strip_prefix(root_path) {
+ $0if let Ok(rel_path) = path.strip_prefix(root_path)
+ .and(x)
+ {
let rel_path = RelativePathBuf::from_path(rel_path)
.ok()?;
Some((*id, rel_path))
@@ -971,7 +971,8 @@ fn main() {
r#"
fn main() {
if true {
- match path.strip_prefix(root_path) {
+ match path.strip_prefix(root_path)
+ .and(x) {
Ok(rel_path) => {
let rel_path = RelativePathBuf::from_path(rel_path)
.ok()?;
@@ -993,7 +994,9 @@ fn main() {
r#"
fn main() {
if true {
- $0if let Ok(rel_path) = path.strip_prefix(root_path) {
+ $0if let Ok(rel_path) = path.strip_prefix(root_path)
+ .and(x)
+ {
Foo {
x: 1
}
@@ -1008,7 +1011,8 @@ fn main() {
r#"
fn main() {
if true {
- match path.strip_prefix(root_path) {
+ match path.strip_prefix(root_path)
+ .and(x) {
Ok(rel_path) => {
Foo {
x: 1
@@ -1023,7 +1027,33 @@ fn main() {
}
}
"#,
- )
+ );
+
+ check_assist(
+ replace_if_let_with_match,
+ r#"
+fn main() {
+ if true {
+ $0if true
+ && false
+ {
+ foo()
+ }
+ }
+}
+"#,
+ r#"
+fn main() {
+ if true {
+ match true
+ && false {
+ true => foo(),
+ false => (),
+ }
+ }
+}
+"#,
+ );
}
#[test]
@@ -1878,7 +1908,9 @@ fn foo(x: Result<i32, ()>) {
r#"
fn main() {
if true {
- $0match path.strip_prefix(root_path) {
+ $0match path.strip_prefix(root_path)
+ .and(x)
+ {
Ok(rel_path) => Foo {
x: 2
}
@@ -1892,7 +1924,8 @@ fn main() {
r#"
fn main() {
if true {
- if let Ok(rel_path) = path.strip_prefix(root_path) {
+ if let Ok(rel_path) = path.strip_prefix(root_path)
+ .and(x) {
Foo {
x: 2
}
@@ -1911,7 +1944,9 @@ fn main() {
r#"
fn main() {
if true {
- $0match path.strip_prefix(root_path) {
+ $0match path.strip_prefix(root_path)
+ .and(x)
+ {
Ok(rel_path) => {
let rel_path = RelativePathBuf::from_path(rel_path)
.ok()?;
@@ -1929,7 +1964,8 @@ fn main() {
r#"
fn main() {
if true {
- if let Ok(rel_path) = path.strip_prefix(root_path) {
+ if let Ok(rel_path) = path.strip_prefix(root_path)
+ .and(x) {
let rel_path = RelativePathBuf::from_path(rel_path)
.ok()?;
Some((*id, rel_path))
diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs
index eeb2c65e48..6e9328165d 100644
--- a/crates/ide-completion/src/completions/pattern.rs
+++ b/crates/ide-completion/src/completions/pattern.rs
@@ -95,7 +95,7 @@ pub(crate) fn complete_pattern(
if refutable || single_variant_enum(variant.parent_enum(ctx.db)) =>
{
acc.add_variant_pat(ctx, pattern_ctx, None, variant, Some(name.clone()));
- true
+ false
}
hir::ModuleDef::Adt(hir::Adt::Enum(e)) => refutable || single_variant_enum(e),
hir::ModuleDef::Const(..) => refutable,
diff --git a/crates/ide-completion/src/tests/pattern.rs b/crates/ide-completion/src/tests/pattern.rs
index b8728028bb..0d85f2e9ad 100644
--- a/crates/ide-completion/src/tests/pattern.rs
+++ b/crates/ide-completion/src/tests/pattern.rs
@@ -122,7 +122,6 @@ fn foo() {
st Record
st Tuple
st Unit
- ev TupleV
bn Record {…} Record { field$1 }$0
bn Tuple(…) Tuple($1)$0
bn TupleV(…) TupleV($1)$0
@@ -159,8 +158,6 @@ fn foo(foo: Foo) { match foo { Foo { x: $0 } } }
expect![[r#"
en Bar
st Foo
- ev Nil
- ev Value
bn Foo {…} Foo { x$1 }$0
bn Nil Nil$0
bn Value Value$0
@@ -189,7 +186,6 @@ fn foo() {
st Record
st Tuple
st Unit
- ev Variant
bn Record {…} Record { field$1 }$0
bn Tuple(…) Tuple($1)$0
bn Variant Variant$0
@@ -355,6 +351,34 @@ fn func() {
}
#[test]
+fn enum_unqualified() {
+ check_with_base_items(
+ r#"
+use Enum::*;
+fn func() {
+ if let $0 = unknown {}
+}
+"#,
+ expect![[r#"
+ ct CONST
+ en Enum
+ ma makro!(…) macro_rules! makro
+ md module
+ st Record
+ st Tuple
+ st Unit
+ bn Record {…} Record { field$1 }$0
+ bn RecordV {…} RecordV { field$1 }$0
+ bn Tuple(…) Tuple($1)$0
+ bn TupleV(…) TupleV($1)$0
+ bn UnitV UnitV$0
+ kw mut
+ kw ref
+ "#]],
+ );
+}
+
+#[test]
fn completes_in_record_field_pat() {
check(
r#"
diff --git a/crates/ide-completion/src/tests/record.rs b/crates/ide-completion/src/tests/record.rs
index 045b2d03b0..c1274f6640 100644
--- a/crates/ide-completion/src/tests/record.rs
+++ b/crates/ide-completion/src/tests/record.rs
@@ -61,8 +61,6 @@ fn foo(baz: Baz) {
en Baz
en Result
md core
- ev Err
- ev Ok
bn Baz::Bar Baz::Bar$0
bn Baz::Foo Baz::Foo$0
bn Err(…) Err($1)$0
@@ -89,10 +87,6 @@ fn foo(baz: Baz) {
en Baz
en Result
md core
- ev Bar
- ev Err
- ev Foo
- ev Ok
bn Bar Bar$0
bn Err(…) Err($1)$0
bn Foo Foo$0
diff --git a/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/crates/ide-diagnostics/src/handlers/invalid_cast.rs
index 7479f8147d..405d8df685 100644
--- a/crates/ide-diagnostics/src/handlers/invalid_cast.rs
+++ b/crates/ide-diagnostics/src/handlers/invalid_cast.rs
@@ -517,11 +517,13 @@ trait Trait<'a> {}
fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) {
x as _
+ //^^^^^^ error: cannot add auto trait to dyn bound via pointer cast
}
// (to test diagnostic list formatting)
fn add_multiple_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send + Sync + Unpin) {
x as _
+ //^^^^^^ error: cannot add auto trait to dyn bound via pointer cast
}
"#,
);
diff --git a/crates/load-cargo/src/lib.rs b/crates/load-cargo/src/lib.rs
index 654ff4f75b..b8ce3a8da4 100644
--- a/crates/load-cargo/src/lib.rs
+++ b/crates/load-cargo/src/lib.rs
@@ -26,7 +26,7 @@ use ide_db::{
use itertools::Itertools;
use proc_macro_api::{
MacroDylib, ProcMacroClient,
- bidirectional_protocol::msg::{SubRequest, SubResponse},
+ bidirectional_protocol::msg::{ParentSpan, SubRequest, SubResponse},
};
use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace};
use span::{Span, SpanAnchor, SyntaxContext};
@@ -659,6 +659,44 @@ impl ProcMacroExpander for Expander {
ctx: current_span.ctx.into_u32(),
})
}
+ SubRequest::SpanParent { file_id, ast_id, start, end, ctx } => {
+ let span = Span {
+ range: TextRange::new(TextSize::from(start), TextSize::from(end)),
+ anchor: SpanAnchor {
+ file_id: span::EditionedFileId::from_raw(file_id),
+ ast_id: span::ErasedFileAstId::from_raw(ast_id),
+ },
+ // SAFETY: We only receive spans from the server. If someone mess up the communication UB can happen,
+ // but that will be their problem.
+ ctx: unsafe { SyntaxContext::from_u32(ctx) },
+ };
+
+ if let Some(macro_call_id) = span.ctx.outer_expn(db) {
+ let macro_call_loc = db.lookup_intern_macro_call(macro_call_id.into());
+
+ let call_site_file = macro_call_loc.kind.file_id();
+ let call_site_ast_id = macro_call_loc.kind.erased_ast_id();
+
+ if let Some(editioned_file_id) = call_site_file.file_id() {
+ let range = db
+ .ast_id_map(editioned_file_id.into())
+ .get_erased(call_site_ast_id)
+ .text_range();
+
+ let parent_span = Some(ParentSpan {
+ file_id: editioned_file_id.editioned_file_id(db).as_u32(),
+ ast_id: span::ROOT_ERASED_FILE_AST_ID.into_raw(),
+ start: u32::from(range.start()),
+ end: u32::from(range.end()),
+ ctx: macro_call_loc.ctxt.into_u32(),
+ });
+
+ return Ok(SubResponse::SpanParentResult { parent_span });
+ }
+ }
+
+ Ok(SubResponse::SpanParentResult { parent_span: None })
+ }
};
match self.0.expand(
subtree.view(),
diff --git a/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/crates/proc-macro-api/src/bidirectional_protocol/msg.rs
index 10a8d66677..ab4bed81e6 100644
--- a/crates/proc-macro-api/src/bidirectional_protocol/msg.rs
+++ b/crates/proc-macro-api/src/bidirectional_protocol/msg.rs
@@ -22,6 +22,7 @@ pub enum SubRequest {
LineColumn { file_id: u32, ast_id: u32, offset: u32 },
ByteRange { file_id: u32, ast_id: u32, start: u32, end: u32 },
SpanSource { file_id: u32, ast_id: u32, start: u32, end: u32, ctx: u32 },
+ SpanParent { file_id: u32, ast_id: u32, start: u32, end: u32, ctx: u32 },
}
#[derive(Debug, Serialize, Deserialize)]
@@ -50,12 +51,24 @@ pub enum SubResponse {
end: u32,
ctx: u32,
},
+ SpanParentResult {
+ parent_span: Option<ParentSpan>,
+ },
Cancel {
reason: String,
},
}
#[derive(Debug, Serialize, Deserialize)]
+pub struct ParentSpan {
+ pub file_id: u32,
+ pub ast_id: u32,
+ pub start: u32,
+ pub end: u32,
+ pub ctx: u32,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
pub enum BidirectionalMessage {
Request(Request),
Response(Response),
diff --git a/crates/proc-macro-srv-cli/src/main_loop.rs b/crates/proc-macro-srv-cli/src/main_loop.rs
index 2c54b18077..c525ed848b 100644
--- a/crates/proc-macro-srv-cli/src/main_loop.rs
+++ b/crates/proc-macro-srv-cli/src/main_loop.rs
@@ -309,6 +309,40 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> {
other => handle_failure(other),
}
}
+
+ fn span_parent(
+ &mut self,
+ proc_macro_srv::span::Span { range, anchor, ctx }: proc_macro_srv::span::Span,
+ ) -> Option<proc_macro_srv::span::Span> {
+ let response = self.roundtrip(bidirectional::SubRequest::SpanParent {
+ file_id: anchor.file_id.as_u32(),
+ ast_id: anchor.ast_id.into_raw(),
+ start: range.start().into(),
+ end: range.end().into(),
+ ctx: ctx.into_u32(),
+ });
+
+ match response {
+ Ok(bidirectional::SubResponse::SpanParentResult { parent_span }) => {
+ parent_span.map(|bidirectional::ParentSpan { file_id, ast_id, start, end, ctx }| {
+ proc_macro_srv::span::Span {
+ range: proc_macro_srv::span::TextRange::new(
+ proc_macro_srv::span::TextSize::new(start),
+ proc_macro_srv::span::TextSize::new(end),
+ ),
+ anchor: proc_macro_srv::span::SpanAnchor {
+ file_id: proc_macro_srv::span::EditionedFileId::from_raw(file_id),
+ ast_id: proc_macro_srv::span::ErasedFileAstId::from_raw(ast_id),
+ },
+ // SAFETY: spans originate from the server. If the protocol is violated,
+ // undefined behavior is the caller’s responsibility.
+ ctx: unsafe { proc_macro_srv::span::SyntaxContext::from_u32(ctx) },
+ }
+ })
+ }
+ other => handle_failure(other),
+ }
+ }
}
fn handle_expand_ra(
diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs
index 6b770e440c..65de804404 100644
--- a/crates/proc-macro-srv/src/lib.rs
+++ b/crates/proc-macro-srv/src/lib.rs
@@ -121,6 +121,7 @@ pub trait ProcMacroClientInterface {
fn byte_range(&mut self, span: Span) -> Range<usize>;
fn span_source(&mut self, span: Span) -> Span;
+ fn span_parent(&mut self, span: Span) -> Option<Span>;
}
const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024;
diff --git a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
index 5eb16c37ac..6b6bfcc934 100644
--- a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
+++ b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs
@@ -164,8 +164,10 @@ impl server::Server for RaSpanServer<'_> {
self.callback.as_mut()?.source_text(span)
}
- fn span_parent(&mut self, _span: Self::Span) -> Option<Self::Span> {
- // FIXME requires db, looks up the parent call site
+ fn span_parent(&mut self, span: Self::Span) -> Option<Self::Span> {
+ if let Some(ref mut callback) = self.callback {
+ return callback.span_parent(span);
+ }
None
}
fn span_source(&mut self, span: Self::Span) -> Self::Span {
diff --git a/crates/proc-macro-srv/src/tests/utils.rs b/crates/proc-macro-srv/src/tests/utils.rs
index 28d826d01e..31beca20d6 100644
--- a/crates/proc-macro-srv/src/tests/utils.rs
+++ b/crates/proc-macro-srv/src/tests/utils.rs
@@ -146,6 +146,10 @@ impl ProcMacroClientInterface for MockCallback<'_> {
fn span_source(&mut self, span: Span) -> Span {
span
}
+
+ fn span_parent(&mut self, _span: Span) -> Option<Span> {
+ None
+ }
}
pub fn assert_expand_with_callback(
diff --git a/crates/project-model/src/cargo_config_file.rs b/crates/project-model/src/cargo_config_file.rs
index ae36deb71f..9c7f109a62 100644
--- a/crates/project-model/src/cargo_config_file.rs
+++ b/crates/project-model/src/cargo_config_file.rs
@@ -158,14 +158,15 @@ pub(crate) fn make_lockfile_copy(
build: semver::BuildMetadata::EMPTY,
};
- const MINIMUM_TOOLCHAIN_VERSION_SUPPORTING_LOCKFILE_PATH_ENV: semver::Version =
- semver::Version {
- major: 1,
- minor: 95,
- patch: 0,
- pre: semver::Prerelease::EMPTY,
- build: semver::BuildMetadata::EMPTY,
- };
+ // TODO: turn this into a const and remove pre once 1.95 is stable
+ #[allow(non_snake_case)]
+ let MINIMUM_TOOLCHAIN_VERSION_SUPPORTING_LOCKFILE_PATH_ENV: semver::Version = semver::Version {
+ major: 1,
+ minor: 95,
+ patch: 0,
+ pre: semver::Prerelease::new("nightly").unwrap(),
+ build: semver::BuildMetadata::EMPTY,
+ };
let usage = if *toolchain_version >= MINIMUM_TOOLCHAIN_VERSION_SUPPORTING_LOCKFILE_PATH_ENV {
LockfileUsage::WithEnvVar
diff --git a/crates/rust-analyzer/src/handlers/dispatch.rs b/crates/rust-analyzer/src/handlers/dispatch.rs
index 90deae2d90..67bd643fce 100644
--- a/crates/rust-analyzer/src/handlers/dispatch.rs
+++ b/crates/rust-analyzer/src/handlers/dispatch.rs
@@ -414,7 +414,8 @@ impl NotificationDispatcher<'_> {
let params = match not.extract::<N::Params>(N::METHOD) {
Ok(it) => it,
Err(ExtractError::JsonError { method, error }) => {
- panic!("Invalid request\nMethod: {method}\n error: {error}",)
+ tracing::error!(method = %method, error = %error, "invalid notification");
+ return self;
}
Err(ExtractError::MethodMismatch(not)) => {
self.not = Some(not);
diff --git a/crates/rust-analyzer/tests/slow-tests/main.rs b/crates/rust-analyzer/tests/slow-tests/main.rs
index 26ba549a29..fcdc8bb7cd 100644
--- a/crates/rust-analyzer/tests/slow-tests/main.rs
+++ b/crates/rust-analyzer/tests/slow-tests/main.rs
@@ -22,6 +22,7 @@ mod testdir;
use std::{collections::HashMap, path::PathBuf, time::Instant};
+use ide_db::FxHashMap;
use lsp_types::{
CodeActionContext, CodeActionParams, CompletionParams, DidOpenTextDocumentParams,
DocumentFormattingParams, DocumentRangeFormattingParams, FileRename, FormattingOptions,
@@ -673,6 +674,17 @@ fn test_format_document_range() {
return;
}
+ // This test requires a nightly toolchain, so skip if it's not available.
+ let cwd = std::env::current_dir().unwrap_or_default();
+ let has_nightly_rustfmt = toolchain::command("rustfmt", cwd, &FxHashMap::default())
+ .args(["+nightly", "--version"])
+ .output()
+ .is_ok_and(|out| out.status.success());
+ if !has_nightly_rustfmt {
+ tracing::warn!("skipping test_format_document_range: nightly rustfmt not available");
+ return;
+ }
+
let server = Project::with_fixture(
r#"
//- /Cargo.toml
diff --git a/crates/syntax/src/ast/syntax_factory/constructors.rs b/crates/syntax/src/ast/syntax_factory/constructors.rs
index 6e17d262a7..27182191c3 100644
--- a/crates/syntax/src/ast/syntax_factory/constructors.rs
+++ b/crates/syntax/src/ast/syntax_factory/constructors.rs
@@ -79,8 +79,12 @@ impl SyntaxFactory {
make::path_concat(first, second).clone_for_update()
}
+ pub fn visibility_pub_crate(&self) -> ast::Visibility {
+ make::visibility_pub_crate().clone_for_update()
+ }
+
pub fn visibility_pub(&self) -> ast::Visibility {
- make::visibility_pub()
+ make::visibility_pub().clone_for_update()
}
pub fn struct_(