Skip to content

Commit 706f244

Browse files
committed
Auto merge of #142907 - lnicola:sync-from-ra, r=lnicola
Subtree update of `rust-analyzer` r? `@ghost`
2 parents 42245d3 + 9a0434e commit 706f244

File tree

117 files changed

+2756
-1241
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+2756
-1241
lines changed

src/tools/rust-analyzer/crates/hir-def/src/db.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ use syntax::{AstPtr, ast};
1111
use triomphe::Arc;
1212

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

9191
#[salsa::interned]
9292
fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId;
93-
// // endregion: items
93+
// endregion: items
94+
95+
#[salsa::interned]
96+
fn intern_block(&self, loc: BlockLoc) -> BlockId;
9497
}
9598

9699
#[query_group::query_group]

src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs

Lines changed: 217 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use base_db::FxIndexSet;
1111
use cfg::CfgOptions;
1212
use either::Either;
1313
use hir_expand::{
14-
HirFileId, InFile, Intern, MacroDefId,
14+
HirFileId, InFile, MacroDefId,
1515
mod_path::tool_path,
1616
name::{AsName, Name},
1717
span_map::SpanMapRef,
@@ -2148,7 +2148,7 @@ impl ExprCollector<'_> {
21482148
) -> ExprId {
21492149
let block_id = self.expander.ast_id_map().ast_id_for_block(&block).map(|file_local_id| {
21502150
let ast_id = self.expander.in_file(file_local_id);
2151-
BlockLoc { ast_id, module: self.module }.intern(self.db)
2151+
self.db.intern_block(BlockLoc { ast_id, module: self.module })
21522152
});
21532153

21542154
let (module, def_map) =
@@ -2815,6 +2815,51 @@ impl ExprCollector<'_> {
28152815
mutability: Mutability::Shared,
28162816
})
28172817
};
2818+
2819+
// Assume that rustc version >= 1.89.0 iff lang item `format_arguments` exists
2820+
// but `format_unsafe_arg` does not
2821+
let fmt_args =
2822+
|| crate::lang_item::lang_item(self.db, self.module.krate(), LangItem::FormatArguments);
2823+
let fmt_unsafe_arg =
2824+
|| crate::lang_item::lang_item(self.db, self.module.krate(), LangItem::FormatUnsafeArg);
2825+
let use_format_args_since_1_89_0 = fmt_args().is_some() && fmt_unsafe_arg().is_none();
2826+
2827+
let idx = if use_format_args_since_1_89_0 {
2828+
self.collect_format_args_impl(
2829+
syntax_ptr,
2830+
fmt,
2831+
hygiene,
2832+
argmap,
2833+
lit_pieces,
2834+
format_options,
2835+
)
2836+
} else {
2837+
self.collect_format_args_before_1_89_0_impl(
2838+
syntax_ptr,
2839+
fmt,
2840+
argmap,
2841+
lit_pieces,
2842+
format_options,
2843+
)
2844+
};
2845+
2846+
self.source_map
2847+
.template_map
2848+
.get_or_insert_with(Default::default)
2849+
.format_args_to_captures
2850+
.insert(idx, (hygiene, mappings));
2851+
idx
2852+
}
2853+
2854+
/// `format_args!` expansion implementation for rustc versions < `1.89.0`
2855+
fn collect_format_args_before_1_89_0_impl(
2856+
&mut self,
2857+
syntax_ptr: AstPtr<ast::Expr>,
2858+
fmt: FormatArgs,
2859+
argmap: FxIndexSet<(usize, ArgumentType)>,
2860+
lit_pieces: ExprId,
2861+
format_options: ExprId,
2862+
) -> ExprId {
28182863
let arguments = &*fmt.arguments.arguments;
28192864

28202865
let args = if arguments.is_empty() {
@@ -2902,19 +2947,181 @@ impl ExprCollector<'_> {
29022947
});
29032948
}
29042949

2905-
let idx = self.alloc_expr(
2950+
self.alloc_expr(
29062951
Expr::Call {
29072952
callee: new_v1_formatted,
29082953
args: Box::new([lit_pieces, args, format_options, unsafe_arg_new]),
29092954
},
29102955
syntax_ptr,
2911-
);
2912-
self.source_map
2913-
.template_map
2914-
.get_or_insert_with(Default::default)
2915-
.format_args_to_captures
2916-
.insert(idx, (hygiene, mappings));
2917-
idx
2956+
)
2957+
}
2958+
2959+
/// `format_args!` expansion implementation for rustc versions >= `1.89.0`,
2960+
/// especially since [this PR](https://github.com/rust-lang/rust/pull/140748)
2961+
fn collect_format_args_impl(
2962+
&mut self,
2963+
syntax_ptr: AstPtr<ast::Expr>,
2964+
fmt: FormatArgs,
2965+
hygiene: HygieneId,
2966+
argmap: FxIndexSet<(usize, ArgumentType)>,
2967+
lit_pieces: ExprId,
2968+
format_options: ExprId,
2969+
) -> ExprId {
2970+
let arguments = &*fmt.arguments.arguments;
2971+
2972+
let (let_stmts, args) = if arguments.is_empty() {
2973+
(
2974+
// Generate:
2975+
// []
2976+
vec![],
2977+
self.alloc_expr_desugared(Expr::Array(Array::ElementList {
2978+
elements: Box::default(),
2979+
})),
2980+
)
2981+
} else if argmap.len() == 1 && arguments.len() == 1 {
2982+
// Only one argument, so we don't need to make the `args` tuple.
2983+
//
2984+
// Generate:
2985+
// super let args = [<core::fmt::Arguments>::new_display(&arg)];
2986+
let args = argmap
2987+
.iter()
2988+
.map(|&(arg_index, ty)| {
2989+
let ref_arg = self.alloc_expr_desugared(Expr::Ref {
2990+
expr: arguments[arg_index].expr,
2991+
rawness: Rawness::Ref,
2992+
mutability: Mutability::Shared,
2993+
});
2994+
self.make_argument(ref_arg, ty)
2995+
})
2996+
.collect();
2997+
let args =
2998+
self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: args }));
2999+
let args_name = Name::new_symbol_root(sym::args);
3000+
let args_binding =
3001+
self.alloc_binding(args_name.clone(), BindingAnnotation::Unannotated, hygiene);
3002+
let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None });
3003+
self.add_definition_to_binding(args_binding, args_pat);
3004+
// TODO: We don't have `super let` yet.
3005+
let let_stmt = Statement::Let {
3006+
pat: args_pat,
3007+
type_ref: None,
3008+
initializer: Some(args),
3009+
else_branch: None,
3010+
};
3011+
(vec![let_stmt], self.alloc_expr_desugared(Expr::Path(Path::from(args_name))))
3012+
} else {
3013+
// Generate:
3014+
// super let args = (&arg0, &arg1, &...);
3015+
let args_name = Name::new_symbol_root(sym::args);
3016+
let args_binding =
3017+
self.alloc_binding(args_name.clone(), BindingAnnotation::Unannotated, hygiene);
3018+
let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None });
3019+
self.add_definition_to_binding(args_binding, args_pat);
3020+
let elements = arguments
3021+
.iter()
3022+
.map(|arg| {
3023+
self.alloc_expr_desugared(Expr::Ref {
3024+
expr: arg.expr,
3025+
rawness: Rawness::Ref,
3026+
mutability: Mutability::Shared,
3027+
})
3028+
})
3029+
.collect();
3030+
let args_tuple = self.alloc_expr_desugared(Expr::Tuple { exprs: elements });
3031+
// TODO: We don't have `super let` yet
3032+
let let_stmt1 = Statement::Let {
3033+
pat: args_pat,
3034+
type_ref: None,
3035+
initializer: Some(args_tuple),
3036+
else_branch: None,
3037+
};
3038+
3039+
// Generate:
3040+
// super let args = [
3041+
// <core::fmt::Argument>::new_display(args.0),
3042+
// <core::fmt::Argument>::new_lower_hex(args.1),
3043+
// <core::fmt::Argument>::new_debug(args.0),
3044+
// …
3045+
// ];
3046+
let args = argmap
3047+
.iter()
3048+
.map(|&(arg_index, ty)| {
3049+
let args_ident_expr =
3050+
self.alloc_expr_desugared(Expr::Path(args_name.clone().into()));
3051+
let arg = self.alloc_expr_desugared(Expr::Field {
3052+
expr: args_ident_expr,
3053+
name: Name::new_tuple_field(arg_index),
3054+
});
3055+
self.make_argument(arg, ty)
3056+
})
3057+
.collect();
3058+
let array =
3059+
self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: args }));
3060+
let args_binding =
3061+
self.alloc_binding(args_name.clone(), BindingAnnotation::Unannotated, hygiene);
3062+
let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None });
3063+
self.add_definition_to_binding(args_binding, args_pat);
3064+
let let_stmt2 = Statement::Let {
3065+
pat: args_pat,
3066+
type_ref: None,
3067+
initializer: Some(array),
3068+
else_branch: None,
3069+
};
3070+
(vec![let_stmt1, let_stmt2], self.alloc_expr_desugared(Expr::Path(args_name.into())))
3071+
};
3072+
3073+
// Generate:
3074+
// &args
3075+
let args = self.alloc_expr_desugared(Expr::Ref {
3076+
expr: args,
3077+
rawness: Rawness::Ref,
3078+
mutability: Mutability::Shared,
3079+
});
3080+
3081+
let call_block = {
3082+
// Generate:
3083+
// unsafe {
3084+
// <core::fmt::Arguments>::new_v1_formatted(
3085+
// lit_pieces,
3086+
// args,
3087+
// format_options,
3088+
// )
3089+
// }
3090+
3091+
let new_v1_formatted = LangItem::FormatArguments.ty_rel_path(
3092+
self.db,
3093+
self.module.krate(),
3094+
Name::new_symbol_root(sym::new_v1_formatted),
3095+
);
3096+
let new_v1_formatted =
3097+
self.alloc_expr_desugared(new_v1_formatted.map_or(Expr::Missing, Expr::Path));
3098+
let args = [lit_pieces, args, format_options];
3099+
let call = self
3100+
.alloc_expr_desugared(Expr::Call { callee: new_v1_formatted, args: args.into() });
3101+
3102+
Expr::Unsafe { id: None, statements: Box::default(), tail: Some(call) }
3103+
};
3104+
3105+
if !let_stmts.is_empty() {
3106+
// Generate:
3107+
// {
3108+
// super let …
3109+
// super let …
3110+
// <core::fmt::Arguments>::new_…(…)
3111+
// }
3112+
let call = self.alloc_expr_desugared(call_block);
3113+
self.alloc_expr(
3114+
Expr::Block {
3115+
id: None,
3116+
statements: let_stmts.into(),
3117+
tail: Some(call),
3118+
label: None,
3119+
},
3120+
syntax_ptr,
3121+
)
3122+
} else {
3123+
self.alloc_expr(call_block, syntax_ptr)
3124+
}
29183125
}
29193126

29203127
/// Generate a hir expression for a format_args placeholder specification.

0 commit comments

Comments
 (0)