Skip to content

Subtree update of rust-analyzer #142907

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 43 commits into from
Jun 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
2a473e5
In "Fill match arms", allow users to prefer `Self` to the enum name w…
ChayimFriedman2 Jun 6, 2025
5b1ac61
Add the quickfix for increasing visibility of a private field to the …
ChayimFriedman2 Jun 8, 2025
13f5866
feat: Show what cargo metadata is doing in status
Veykril Jun 16, 2025
233e1a8
Merge pull request #20014 from Veykril/push-lsqvxunvnrqw
Veykril Jun 16, 2025
a38a9a6
feat: Insert required parentheses when typing `+` in trait type
Veykril Jun 16, 2025
cc8cf56
Merge pull request #20015 from Veykril/push-wsxzsuurqwwr
Veykril Jun 16, 2025
703856f
fix: Copy lockfiles into target directory before invoking `cargo meta…
Veykril Jun 17, 2025
e4e01f6
Merge pull request #19945 from ChayimFriedman2/private-field-quickfix
Veykril Jun 17, 2025
3b9ef28
Merge pull request #19939 from ChayimFriedman2/fill-arms-self
Veykril Jun 17, 2025
69886cf
Merge pull request #20018 from Veykril/push-pkowrtoturkr
Veykril Jun 17, 2025
8e86b84
chore: Start infesting ide crates with 'db lifetime
Veykril Apr 1, 2025
c860169
Merge pull request #19495 from Veykril/push-woywmrxrtqqy
Veykril Jun 17, 2025
7d10a14
fix: Reload workspaces when cargo configs change
Veykril Jun 17, 2025
3341b65
Merge pull request #20020 from Veykril/push-yuqmorzsqumw
Veykril Jun 17, 2025
a1aac53
Never make type mismatch diagnostic stable, even when there is a fix
ChayimFriedman2 Jun 17, 2025
e0c5fcb
Merge pull request #20022 from ChayimFriedman2/type-mismatch-exp
Veykril Jun 17, 2025
646fecf
Improve completions in if / while expression conditions
Veykril Jun 17, 2025
7ba853c
Better completion test sorting
Veykril Jun 17, 2025
5f2cf7e
Merge pull request #20023 from Veykril/push-vkqlnyttnqzl
Veykril Jun 17, 2025
1f24f02
Hide imported privates if private editable is disabled
SoxPopuli Jun 17, 2025
20a62ab
Merge pull request #20025 from SoxPopuli/hide_private_imports_without_pe
lnicola Jun 17, 2025
5d1a869
Preparing for merge from rust-lang/rust
lnicola Jun 18, 2025
96e1d73
Merge from rust-lang/rust
lnicola Jun 18, 2025
e7971e4
Merge pull request #20032 from lnicola/sync-from-rust
lnicola Jun 18, 2025
b4f09d7
Add --color=always to test explorer command
joshka Jun 18, 2025
70f376d
fix: Closure capturing for let exprs
ShoyuVanilla Jun 18, 2025
58d4b99
Merge pull request #20039 from ShoyuVanilla/let-bind-ref-capt
Veykril Jun 19, 2025
d41f48f
Revert "Turn `BlockId` into a `#[salsa::tracked]`"
Veykril Jun 19, 2025
dd8eaaa
Merge pull request #20041 from Veykril/push-yxlszoznuyno
Veykril Jun 19, 2025
80bd8a4
fix: Temporarily disable `+` typing handler as it moves the cursor po…
Veykril Jun 19, 2025
b8cc805
Merge pull request #20042 from Veykril/push-uosxynulorzn
Veykril Jun 19, 2025
7785869
Add `fn parent(self, db) -> GenericDef` to `hir::TypeParam`
regexident Jun 19, 2025
2a6ace3
Merge pull request #20035 from joshka/jm/test-explorer-color
HKalbasi Jun 20, 2025
808e066
Merge pull request #20046 from regexident/type-param-parent-getter
flodiebold Jun 20, 2025
af3f9d1
Add better documentation for excluding imports from symbol search
LHolten Jun 20, 2025
8329c93
internal: Utilize `cargo check --compile-time-deps`
ShoyuVanilla Jun 19, 2025
29a8b83
fix: Correct grammar in remove all unused imports assist
ze Jun 21, 2025
9d76126
Merge pull request #20053 from ze/master
lnicola Jun 21, 2025
110bacd
Merge pull request #20047 from ShoyuVanilla/comp-time-deps
Veykril Jun 21, 2025
3fb8acb
Merge pull request #20050 from LHolten/better-docs-for-exclude-import…
ChayimFriedman2 Jun 21, 2025
17a8ba9
Implement region negation to minicore and add a flag `fmt_before_1_89_0`
ShoyuVanilla Jun 21, 2025
03a8268
Minic rustc's new `format_args!` expansion
ShoyuVanilla Jun 21, 2025
9a0434e
Merge pull request #20056 from ShoyuVanilla/fmt-args-new
ChayimFriedman2 Jun 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions src/tools/rust-analyzer/crates/hir-def/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ use syntax::{AstPtr, ast};
use triomphe::Arc;

use crate::{
AssocItemId, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, EnumVariantId,
EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId,
FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, MacroExpander,
MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId,
StaticLoc, StructId, StructLoc, TraitAliasId, TraitAliasLoc, TraitId, TraitLoc, TypeAliasId,
TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId,
AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc,
EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc,
FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc,
MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId,
ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitAliasId, TraitAliasLoc, TraitId,
TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId,
attr::{Attrs, AttrsWithOwner},
expr_store::{
Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, scope::ExprScopes,
Expand Down Expand Up @@ -90,7 +90,10 @@ pub trait InternDatabase: RootQueryDb {

#[salsa::interned]
fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId;
// // endregion: items
// endregion: items

#[salsa::interned]
fn intern_block(&self, loc: BlockLoc) -> BlockId;
}

#[query_group::query_group]
Expand Down
227 changes: 217 additions & 10 deletions src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use base_db::FxIndexSet;
use cfg::CfgOptions;
use either::Either;
use hir_expand::{
HirFileId, InFile, Intern, MacroDefId,
HirFileId, InFile, MacroDefId,
mod_path::tool_path,
name::{AsName, Name},
span_map::SpanMapRef,
Expand Down Expand Up @@ -2148,7 +2148,7 @@ impl ExprCollector<'_> {
) -> ExprId {
let block_id = self.expander.ast_id_map().ast_id_for_block(&block).map(|file_local_id| {
let ast_id = self.expander.in_file(file_local_id);
BlockLoc { ast_id, module: self.module }.intern(self.db)
self.db.intern_block(BlockLoc { ast_id, module: self.module })
});

let (module, def_map) =
Expand Down Expand Up @@ -2815,6 +2815,51 @@ impl ExprCollector<'_> {
mutability: Mutability::Shared,
})
};

// Assume that rustc version >= 1.89.0 iff lang item `format_arguments` exists
// but `format_unsafe_arg` does not
let fmt_args =
|| crate::lang_item::lang_item(self.db, self.module.krate(), LangItem::FormatArguments);
let fmt_unsafe_arg =
|| crate::lang_item::lang_item(self.db, self.module.krate(), LangItem::FormatUnsafeArg);
let use_format_args_since_1_89_0 = fmt_args().is_some() && fmt_unsafe_arg().is_none();

let idx = if use_format_args_since_1_89_0 {
self.collect_format_args_impl(
syntax_ptr,
fmt,
hygiene,
argmap,
lit_pieces,
format_options,
)
} else {
self.collect_format_args_before_1_89_0_impl(
syntax_ptr,
fmt,
argmap,
lit_pieces,
format_options,
)
};

self.source_map
.template_map
.get_or_insert_with(Default::default)
.format_args_to_captures
.insert(idx, (hygiene, mappings));
idx
}

/// `format_args!` expansion implementation for rustc versions < `1.89.0`
fn collect_format_args_before_1_89_0_impl(
&mut self,
syntax_ptr: AstPtr<ast::Expr>,
fmt: FormatArgs,
argmap: FxIndexSet<(usize, ArgumentType)>,
lit_pieces: ExprId,
format_options: ExprId,
) -> ExprId {
let arguments = &*fmt.arguments.arguments;

let args = if arguments.is_empty() {
Expand Down Expand Up @@ -2902,19 +2947,181 @@ impl ExprCollector<'_> {
});
}

let idx = self.alloc_expr(
self.alloc_expr(
Expr::Call {
callee: new_v1_formatted,
args: Box::new([lit_pieces, args, format_options, unsafe_arg_new]),
},
syntax_ptr,
);
self.source_map
.template_map
.get_or_insert_with(Default::default)
.format_args_to_captures
.insert(idx, (hygiene, mappings));
idx
)
}

/// `format_args!` expansion implementation for rustc versions >= `1.89.0`,
/// especially since [this PR](https://github.com/rust-lang/rust/pull/140748)
fn collect_format_args_impl(
&mut self,
syntax_ptr: AstPtr<ast::Expr>,
fmt: FormatArgs,
hygiene: HygieneId,
argmap: FxIndexSet<(usize, ArgumentType)>,
lit_pieces: ExprId,
format_options: ExprId,
) -> ExprId {
let arguments = &*fmt.arguments.arguments;

let (let_stmts, args) = if arguments.is_empty() {
(
// Generate:
// []
vec![],
self.alloc_expr_desugared(Expr::Array(Array::ElementList {
elements: Box::default(),
})),
)
} else if argmap.len() == 1 && arguments.len() == 1 {
// Only one argument, so we don't need to make the `args` tuple.
//
// Generate:
// super let args = [<core::fmt::Arguments>::new_display(&arg)];
let args = argmap
.iter()
.map(|&(arg_index, ty)| {
let ref_arg = self.alloc_expr_desugared(Expr::Ref {
expr: arguments[arg_index].expr,
rawness: Rawness::Ref,
mutability: Mutability::Shared,
});
self.make_argument(ref_arg, ty)
})
.collect();
let args =
self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: args }));
let args_name = Name::new_symbol_root(sym::args);
let args_binding =
self.alloc_binding(args_name.clone(), BindingAnnotation::Unannotated, hygiene);
let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None });
self.add_definition_to_binding(args_binding, args_pat);
// TODO: We don't have `super let` yet.
let let_stmt = Statement::Let {
pat: args_pat,
type_ref: None,
initializer: Some(args),
else_branch: None,
};
(vec![let_stmt], self.alloc_expr_desugared(Expr::Path(Path::from(args_name))))
} else {
// Generate:
// super let args = (&arg0, &arg1, &...);
let args_name = Name::new_symbol_root(sym::args);
let args_binding =
self.alloc_binding(args_name.clone(), BindingAnnotation::Unannotated, hygiene);
let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None });
self.add_definition_to_binding(args_binding, args_pat);
let elements = arguments
.iter()
.map(|arg| {
self.alloc_expr_desugared(Expr::Ref {
expr: arg.expr,
rawness: Rawness::Ref,
mutability: Mutability::Shared,
})
})
.collect();
let args_tuple = self.alloc_expr_desugared(Expr::Tuple { exprs: elements });
// TODO: We don't have `super let` yet
let let_stmt1 = Statement::Let {
pat: args_pat,
type_ref: None,
initializer: Some(args_tuple),
else_branch: None,
};

// Generate:
// super let args = [
// <core::fmt::Argument>::new_display(args.0),
// <core::fmt::Argument>::new_lower_hex(args.1),
// <core::fmt::Argument>::new_debug(args.0),
// …
// ];
let args = argmap
.iter()
.map(|&(arg_index, ty)| {
let args_ident_expr =
self.alloc_expr_desugared(Expr::Path(args_name.clone().into()));
let arg = self.alloc_expr_desugared(Expr::Field {
expr: args_ident_expr,
name: Name::new_tuple_field(arg_index),
});
self.make_argument(arg, ty)
})
.collect();
let array =
self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: args }));
let args_binding =
self.alloc_binding(args_name.clone(), BindingAnnotation::Unannotated, hygiene);
let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None });
self.add_definition_to_binding(args_binding, args_pat);
let let_stmt2 = Statement::Let {
pat: args_pat,
type_ref: None,
initializer: Some(array),
else_branch: None,
};
(vec![let_stmt1, let_stmt2], self.alloc_expr_desugared(Expr::Path(args_name.into())))
};

// Generate:
// &args
let args = self.alloc_expr_desugared(Expr::Ref {
expr: args,
rawness: Rawness::Ref,
mutability: Mutability::Shared,
});

let call_block = {
// Generate:
// unsafe {
// <core::fmt::Arguments>::new_v1_formatted(
// lit_pieces,
// args,
// format_options,
// )
// }

let new_v1_formatted = LangItem::FormatArguments.ty_rel_path(
self.db,
self.module.krate(),
Name::new_symbol_root(sym::new_v1_formatted),
);
let new_v1_formatted =
self.alloc_expr_desugared(new_v1_formatted.map_or(Expr::Missing, Expr::Path));
let args = [lit_pieces, args, format_options];
let call = self
.alloc_expr_desugared(Expr::Call { callee: new_v1_formatted, args: args.into() });

Expr::Unsafe { id: None, statements: Box::default(), tail: Some(call) }
};

if !let_stmts.is_empty() {
// Generate:
// {
// super let …
// super let …
// <core::fmt::Arguments>::new_…(…)
// }
let call = self.alloc_expr_desugared(call_block);
self.alloc_expr(
Expr::Block {
id: None,
statements: let_stmts.into(),
tail: Some(call),
label: None,
},
syntax_ptr,
)
} else {
self.alloc_expr(call_block, syntax_ptr)
}
}

/// Generate a hir expression for a format_args placeholder specification.
Expand Down
Loading
Loading