Skip to content

Commit 7e00f91

Browse files
authored
Merge pull request #19531 from Veykril/push-kxyrpznnllkx
fix: Fix `format_args` lowering for >=1.87
2 parents bec5459 + e7ce86d commit 7e00f91

File tree

7 files changed

+129
-54
lines changed

7 files changed

+129
-54
lines changed

crates/base-db/src/lib.rs

+13
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,19 @@ pub struct CrateWorkspaceData {
303303
pub toolchain: Option<Version>,
304304
}
305305

306+
impl CrateWorkspaceData {
307+
pub fn is_atleast_187(&self) -> bool {
308+
const VERSION_187: Version = Version {
309+
major: 1,
310+
minor: 87,
311+
patch: 0,
312+
pre: Prerelease::EMPTY,
313+
build: BuildMetadata::EMPTY,
314+
};
315+
self.toolchain.as_ref().map_or(false, |v| *v >= VERSION_187)
316+
}
317+
}
318+
306319
fn toolchain_channel(db: &dyn RootQueryDb, krate: Crate) -> Option<ReleaseChannel> {
307320
krate.workspace_data(db).toolchain.as_ref().and_then(|v| ReleaseChannel::from_str(&v.pre))
308321
}

crates/hir-def/src/expr_store/lower.rs

+91-46
Original file line numberDiff line numberDiff line change
@@ -2321,54 +2321,99 @@ impl ExprCollector<'_> {
23212321
zero_pad,
23222322
debug_hex,
23232323
} = &placeholder.format_options;
2324-
let fill = self.alloc_expr_desugared(Expr::Literal(Literal::Char(fill.unwrap_or(' '))));
23252324

2326-
let align = {
2327-
let align = LangItem::FormatAlignment.ty_rel_path(
2328-
self.db,
2329-
self.krate,
2330-
match alignment {
2331-
Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left.clone()),
2332-
Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right.clone()),
2333-
Some(FormatAlignment::Center) => Name::new_symbol_root(sym::Center.clone()),
2334-
None => Name::new_symbol_root(sym::Unknown.clone()),
2335-
},
2336-
);
2337-
match align {
2338-
Some(path) => self.alloc_expr_desugared(Expr::Path(path)),
2339-
None => self.missing_expr(),
2340-
}
2341-
};
2342-
// This needs to match `Flag` in library/core/src/fmt/rt.rs.
2343-
let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32)
2344-
| (((sign == Some(FormatSign::Minus)) as u32) << 1)
2345-
| ((alternate as u32) << 2)
2346-
| ((zero_pad as u32) << 3)
2347-
| (((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4)
2348-
| (((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5);
2349-
let flags = self.alloc_expr_desugared(Expr::Literal(Literal::Uint(
2350-
flags as u128,
2351-
Some(BuiltinUint::U32),
2352-
)));
2353-
let precision = self.make_count(precision, argmap);
2354-
let width = self.make_count(width, argmap);
2325+
let precision_expr = self.make_count(precision, argmap);
2326+
let width_expr = self.make_count(width, argmap);
23552327

2356-
let format_placeholder_new = {
2357-
let format_placeholder_new = LangItem::FormatPlaceholder.ty_rel_path(
2358-
self.db,
2359-
self.krate,
2360-
Name::new_symbol_root(sym::new.clone()),
2361-
);
2362-
match format_placeholder_new {
2363-
Some(path) => self.alloc_expr_desugared(Expr::Path(path)),
2364-
None => self.missing_expr(),
2365-
}
2366-
};
2367-
2368-
self.alloc_expr_desugared(Expr::Call {
2369-
callee: format_placeholder_new,
2370-
args: Box::new([position, fill, align, flags, precision, width]),
2371-
})
2328+
if self.krate.workspace_data(self.db).is_atleast_187() {
2329+
// These need to match the constants in library/core/src/fmt/rt.rs.
2330+
let align = match alignment {
2331+
Some(FormatAlignment::Left) => 0,
2332+
Some(FormatAlignment::Right) => 1,
2333+
Some(FormatAlignment::Center) => 2,
2334+
None => 3,
2335+
};
2336+
// This needs to match `Flag` in library/core/src/fmt/rt.rs.
2337+
let flags = fill.unwrap_or(' ') as u32
2338+
| ((sign == Some(FormatSign::Plus)) as u32) << 21
2339+
| ((sign == Some(FormatSign::Minus)) as u32) << 22
2340+
| (alternate as u32) << 23
2341+
| (zero_pad as u32) << 24
2342+
| ((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 25
2343+
| ((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 26
2344+
| (width.is_some() as u32) << 27
2345+
| (precision.is_some() as u32) << 28
2346+
| align << 29
2347+
| 1 << 31; // Highest bit always set.
2348+
let flags = self.alloc_expr_desugared(Expr::Literal(Literal::Uint(
2349+
flags as u128,
2350+
Some(BuiltinUint::U32),
2351+
)));
2352+
2353+
let position = RecordLitField {
2354+
name: Name::new_symbol_root(sym::position.clone()),
2355+
expr: position,
2356+
};
2357+
let flags =
2358+
RecordLitField { name: Name::new_symbol_root(sym::flags.clone()), expr: flags };
2359+
let precision = RecordLitField {
2360+
name: Name::new_symbol_root(sym::precision.clone()),
2361+
expr: precision_expr,
2362+
};
2363+
let width = RecordLitField {
2364+
name: Name::new_symbol_root(sym::width.clone()),
2365+
expr: width_expr,
2366+
};
2367+
self.alloc_expr_desugared(Expr::RecordLit {
2368+
path: LangItem::FormatPlaceholder.path(self.db, self.krate).map(Box::new),
2369+
fields: Box::new([position, flags, precision, width]),
2370+
spread: None,
2371+
})
2372+
} else {
2373+
let format_placeholder_new = {
2374+
let format_placeholder_new = LangItem::FormatPlaceholder.ty_rel_path(
2375+
self.db,
2376+
self.krate,
2377+
Name::new_symbol_root(sym::new.clone()),
2378+
);
2379+
match format_placeholder_new {
2380+
Some(path) => self.alloc_expr_desugared(Expr::Path(path)),
2381+
None => self.missing_expr(),
2382+
}
2383+
};
2384+
// This needs to match `Flag` in library/core/src/fmt/rt.rs.
2385+
let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32)
2386+
| (((sign == Some(FormatSign::Minus)) as u32) << 1)
2387+
| ((alternate as u32) << 2)
2388+
| ((zero_pad as u32) << 3)
2389+
| (((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4)
2390+
| (((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5);
2391+
let flags = self.alloc_expr_desugared(Expr::Literal(Literal::Uint(
2392+
flags as u128,
2393+
Some(BuiltinUint::U32),
2394+
)));
2395+
let fill = self.alloc_expr_desugared(Expr::Literal(Literal::Char(fill.unwrap_or(' '))));
2396+
let align = {
2397+
let align = LangItem::FormatAlignment.ty_rel_path(
2398+
self.db,
2399+
self.krate,
2400+
match alignment {
2401+
Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left.clone()),
2402+
Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right.clone()),
2403+
Some(FormatAlignment::Center) => Name::new_symbol_root(sym::Center.clone()),
2404+
None => Name::new_symbol_root(sym::Unknown.clone()),
2405+
},
2406+
);
2407+
match align {
2408+
Some(path) => self.alloc_expr_desugared(Expr::Path(path)),
2409+
None => self.missing_expr(),
2410+
}
2411+
};
2412+
self.alloc_expr_desugared(Expr::Call {
2413+
callee: format_placeholder_new,
2414+
args: Box::new([position, fill, align, flags, precision_expr, width_expr]),
2415+
})
2416+
}
23722417
}
23732418

23742419
/// Generate a hir expression for a format_args Count.

crates/hir-ty/src/infer.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -1534,10 +1534,6 @@ impl<'a> InferenceContext<'a> {
15341534
None => return (self.err_ty(), None),
15351535
}
15361536
};
1537-
let Some(mod_path) = path.mod_path() else {
1538-
never!("resolver should always resolve lang item paths");
1539-
return (self.err_ty(), None);
1540-
};
15411537
return match resolution {
15421538
TypeNs::AdtId(AdtId::StructId(strukt)) => {
15431539
let substs = path_ctx.substs_from_path(strukt.into(), true);
@@ -1567,6 +1563,10 @@ impl<'a> InferenceContext<'a> {
15671563

15681564
let Some(remaining_idx) = unresolved else {
15691565
drop(ctx);
1566+
let Some(mod_path) = path.mod_path() else {
1567+
never!("resolver should always resolve lang item paths");
1568+
return (self.err_ty(), None);
1569+
};
15701570
return self.resolve_variant_on_alias(ty, None, mod_path);
15711571
};
15721572

@@ -1630,6 +1630,10 @@ impl<'a> InferenceContext<'a> {
16301630
(ty, variant)
16311631
}
16321632
TypeNs::TypeAliasId(it) => {
1633+
let Some(mod_path) = path.mod_path() else {
1634+
never!("resolver should always resolve lang item paths");
1635+
return (self.err_ty(), None);
1636+
};
16331637
let substs = path_ctx.substs_from_path_segment(it.into(), true, None);
16341638
drop(ctx);
16351639
let ty = self.db.ty(it.into());

crates/hir/src/diagnostics.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -570,10 +570,17 @@ impl AnyDiagnostic {
570570
source_map: &hir_def::expr_store::BodySourceMap,
571571
) -> Option<AnyDiagnostic> {
572572
let expr_syntax = |expr| {
573-
source_map.expr_syntax(expr).inspect_err(|_| stdx::never!("synthetic syntax")).ok()
573+
source_map
574+
.expr_syntax(expr)
575+
.inspect_err(|_| stdx::never!("inference diagnostic in desugared expr"))
576+
.ok()
577+
};
578+
let pat_syntax = |pat| {
579+
source_map
580+
.pat_syntax(pat)
581+
.inspect_err(|_| stdx::never!("inference diagnostic in desugared pattern"))
582+
.ok()
574583
};
575-
let pat_syntax =
576-
|pat| source_map.pat_syntax(pat).inspect_err(|_| stdx::never!("synthetic syntax")).ok();
577584
let expr_or_pat_syntax = |id| match id {
578585
ExprOrPatId::ExprId(expr) => expr_syntax(expr),
579586
ExprOrPatId::PatId(pat) => pat_syntax(pat),

crates/ide/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ impl Analysis {
753753
frange: FileRange,
754754
) -> Cancellable<Vec<Assist>> {
755755
let include_fixes = match &assist_config.allowed {
756-
Some(it) => it.iter().any(|&it| it == AssistKind::QuickFix),
756+
Some(it) => it.contains(&AssistKind::QuickFix),
757757
None => true,
758758
};
759759

crates/intern/src/symbol/symbols.rs

+5
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ define_symbols! {
161161
bitxor_assign,
162162
bitxor,
163163
bool,
164+
bootstrap,
164165
box_free,
165166
Box,
166167
boxed,
@@ -525,4 +526,8 @@ define_symbols! {
525526
ignore_flyimport,
526527
ignore_flyimport_methods,
527528
ignore_methods,
529+
position,
530+
flags,
531+
precision,
532+
width,
528533
}

crates/project-model/src/workspace.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,7 @@ fn sysroot_to_crate_graph(
16641664
vec![
16651665
CfgAtom::Flag(sym::debug_assertions.clone()),
16661666
CfgAtom::Flag(sym::miri.clone()),
1667+
CfgAtom::Flag(sym::bootstrap.clone()),
16671668
],
16681669
vec![CfgAtom::Flag(sym::test.clone())],
16691670
),

0 commit comments

Comments
 (0)