Merge pull request #21725 from Veykril/push-skvpqzkooolm fix: Fix wrong confiditon in `Visibility::min`
diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs index d69b00a..fc38361 100644 --- a/crates/hir-ty/src/infer/cast.rs +++ b/crates/hir-ty/src/infer/cast.rs
@@ -328,11 +328,7 @@ // // 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 0fd8057..5134b98 100644 --- a/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/crates/ide-assists/src/handlers/fix_visibility.rs
@@ -2,7 +2,7 @@ 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 @@ 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 @@ } }; - acc.add(AssistId::quick_fix("fix_visibility"), assist_label, target, |edit| { - edit.edit_file(target_file); + acc.add(AssistId::quick_fix("fix_visibility"), assist_label, target, |builder| { + let mut editor = builder.make_editor(vis_owner.syntax()); - let vis_owner = edit.make_mut(vis_owner); - vis_owner.set_visibility(Some(missing_visibility.clone_for_update())); + 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()); - if let Some((cap, vis)) = ctx.config.snippet_cap.zip(vis_owner.visibility()) { - edit.add_tabstop_before(cap, vis); + editor.insert_all( + syntax::syntax_editor::Position::before(vis_before), + vec![missing_visibility.syntax().clone().into(), make.whitespace(" ").into()], + ); } + + 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 06fef4a..3ef68f0 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 @@ }; 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 @@ .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 @@ .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 d2452f2..dcadb53 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 @@ 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 @@ 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 @@ 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 @@ } }; 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } } "#, - ) + ); + + 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 @@ 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 @@ 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 @@ 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 @@ 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 eeb2c65..6e93281 100644 --- a/crates/ide-completion/src/completions/pattern.rs +++ b/crates/ide-completion/src/completions/pattern.rs
@@ -95,7 +95,7 @@ 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 b872802..0d85f2e 100644 --- a/crates/ide-completion/src/tests/pattern.rs +++ b/crates/ide-completion/src/tests/pattern.rs
@@ -122,7 +122,6 @@ 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 @@ 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 @@ 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 @@ } #[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 045b2d0..c1274f6 100644 --- a/crates/ide-completion/src/tests/record.rs +++ b/crates/ide-completion/src/tests/record.rs
@@ -61,8 +61,6 @@ 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 @@ 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 7479f81..405d8df 100644 --- a/crates/ide-diagnostics/src/handlers/invalid_cast.rs +++ b/crates/ide-diagnostics/src/handlers/invalid_cast.rs
@@ -517,11 +517,13 @@ 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 654ff4f..b8ce3a8 100644 --- a/crates/load-cargo/src/lib.rs +++ b/crates/load-cargo/src/lib.rs
@@ -26,7 +26,7 @@ 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 @@ 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 10a8d66..ab4bed8 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 @@ 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 @@ 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 2c54b18..c525ed8 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 @@ 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 6b770e4..65de804 100644 --- a/crates/proc-macro-srv/src/lib.rs +++ b/crates/proc-macro-srv/src/lib.rs
@@ -121,6 +121,7 @@ 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 5eb16c3..6b6bfcc 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 @@ 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 28d826d..31beca2 100644 --- a/crates/proc-macro-srv/src/tests/utils.rs +++ b/crates/proc-macro-srv/src/tests/utils.rs
@@ -146,6 +146,10 @@ 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 ae36deb..9c7f109 100644 --- a/crates/project-model/src/cargo_config_file.rs +++ b/crates/project-model/src/cargo_config_file.rs
@@ -158,14 +158,15 @@ 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 90deae2..67bd643 100644 --- a/crates/rust-analyzer/src/handlers/dispatch.rs +++ b/crates/rust-analyzer/src/handlers/dispatch.rs
@@ -414,7 +414,8 @@ 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/syntax/src/ast/syntax_factory/constructors.rs b/crates/syntax/src/ast/syntax_factory/constructors.rs index 6e17d26..2718219 100644 --- a/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/crates/syntax/src/ast/syntax_factory/constructors.rs
@@ -79,8 +79,12 @@ 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_(