diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs index 83857cf2dd02..9fbeace76c1a 100644 --- a/crates/base-db/src/lib.rs +++ b/crates/base-db/src/lib.rs @@ -303,6 +303,19 @@ pub struct CrateWorkspaceData { pub toolchain: Option, } +impl CrateWorkspaceData { + pub fn is_atleast_187(&self) -> bool { + const VERSION_187: Version = Version { + major: 1, + minor: 87, + patch: 0, + pre: Prerelease::EMPTY, + build: BuildMetadata::EMPTY, + }; + self.toolchain.as_ref().map_or(false, |v| *v >= VERSION_187) + } +} + fn toolchain_channel(db: &dyn RootQueryDb, krate: Crate) -> Option { krate.workspace_data(db).toolchain.as_ref().and_then(|v| ReleaseChannel::from_str(&v.pre)) } diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs index 2d6e8f037f24..1791a1c3175a 100644 --- a/crates/hir-def/src/expr_store/lower.rs +++ b/crates/hir-def/src/expr_store/lower.rs @@ -2321,54 +2321,99 @@ impl ExprCollector<'_> { zero_pad, debug_hex, } = &placeholder.format_options; - let fill = self.alloc_expr_desugared(Expr::Literal(Literal::Char(fill.unwrap_or(' ')))); - let align = { - let align = LangItem::FormatAlignment.ty_rel_path( - self.db, - self.krate, - match alignment { - Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left.clone()), - Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right.clone()), - Some(FormatAlignment::Center) => Name::new_symbol_root(sym::Center.clone()), - None => Name::new_symbol_root(sym::Unknown.clone()), - }, - ); - match align { - Some(path) => self.alloc_expr_desugared(Expr::Path(path)), - None => self.missing_expr(), - } - }; - // This needs to match `Flag` in library/core/src/fmt/rt.rs. - let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32) - | (((sign == Some(FormatSign::Minus)) as u32) << 1) - | ((alternate as u32) << 2) - | ((zero_pad as u32) << 3) - | (((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4) - | (((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5); - let flags = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( - flags as u128, - Some(BuiltinUint::U32), - ))); - let precision = self.make_count(precision, argmap); - let width = self.make_count(width, argmap); + let precision_expr = self.make_count(precision, argmap); + let width_expr = self.make_count(width, argmap); - let format_placeholder_new = { - let format_placeholder_new = LangItem::FormatPlaceholder.ty_rel_path( - self.db, - self.krate, - Name::new_symbol_root(sym::new.clone()), - ); - match format_placeholder_new { - Some(path) => self.alloc_expr_desugared(Expr::Path(path)), - None => self.missing_expr(), - } - }; - - self.alloc_expr_desugared(Expr::Call { - callee: format_placeholder_new, - args: Box::new([position, fill, align, flags, precision, width]), - }) + if self.krate.workspace_data(self.db).is_atleast_187() { + // These need to match the constants in library/core/src/fmt/rt.rs. + let align = match alignment { + Some(FormatAlignment::Left) => 0, + Some(FormatAlignment::Right) => 1, + Some(FormatAlignment::Center) => 2, + None => 3, + }; + // This needs to match `Flag` in library/core/src/fmt/rt.rs. + let flags = fill.unwrap_or(' ') as u32 + | ((sign == Some(FormatSign::Plus)) as u32) << 21 + | ((sign == Some(FormatSign::Minus)) as u32) << 22 + | (alternate as u32) << 23 + | (zero_pad as u32) << 24 + | ((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 25 + | ((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 26 + | (width.is_some() as u32) << 27 + | (precision.is_some() as u32) << 28 + | align << 29 + | 1 << 31; // Highest bit always set. + let flags = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( + flags as u128, + Some(BuiltinUint::U32), + ))); + + let position = RecordLitField { + name: Name::new_symbol_root(sym::position.clone()), + expr: position, + }; + let flags = + RecordLitField { name: Name::new_symbol_root(sym::flags.clone()), expr: flags }; + let precision = RecordLitField { + name: Name::new_symbol_root(sym::precision.clone()), + expr: precision_expr, + }; + let width = RecordLitField { + name: Name::new_symbol_root(sym::width.clone()), + expr: width_expr, + }; + self.alloc_expr_desugared(Expr::RecordLit { + path: LangItem::FormatPlaceholder.path(self.db, self.krate).map(Box::new), + fields: Box::new([position, flags, precision, width]), + spread: None, + }) + } else { + let format_placeholder_new = { + let format_placeholder_new = LangItem::FormatPlaceholder.ty_rel_path( + self.db, + self.krate, + Name::new_symbol_root(sym::new.clone()), + ); + match format_placeholder_new { + Some(path) => self.alloc_expr_desugared(Expr::Path(path)), + None => self.missing_expr(), + } + }; + // This needs to match `Flag` in library/core/src/fmt/rt.rs. + let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32) + | (((sign == Some(FormatSign::Minus)) as u32) << 1) + | ((alternate as u32) << 2) + | ((zero_pad as u32) << 3) + | (((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4) + | (((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5); + let flags = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( + flags as u128, + Some(BuiltinUint::U32), + ))); + let fill = self.alloc_expr_desugared(Expr::Literal(Literal::Char(fill.unwrap_or(' ')))); + let align = { + let align = LangItem::FormatAlignment.ty_rel_path( + self.db, + self.krate, + match alignment { + Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left.clone()), + Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right.clone()), + Some(FormatAlignment::Center) => Name::new_symbol_root(sym::Center.clone()), + None => Name::new_symbol_root(sym::Unknown.clone()), + }, + ); + match align { + Some(path) => self.alloc_expr_desugared(Expr::Path(path)), + None => self.missing_expr(), + } + }; + self.alloc_expr_desugared(Expr::Call { + callee: format_placeholder_new, + args: Box::new([position, fill, align, flags, precision_expr, width_expr]), + }) + } } /// Generate a hir expression for a format_args Count. diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 0bd605c18b4a..0448ecd1ec4a 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -1534,10 +1534,6 @@ impl<'a> InferenceContext<'a> { None => return (self.err_ty(), None), } }; - let Some(mod_path) = path.mod_path() else { - never!("resolver should always resolve lang item paths"); - return (self.err_ty(), None); - }; return match resolution { TypeNs::AdtId(AdtId::StructId(strukt)) => { let substs = path_ctx.substs_from_path(strukt.into(), true); @@ -1567,6 +1563,10 @@ impl<'a> InferenceContext<'a> { let Some(remaining_idx) = unresolved else { drop(ctx); + let Some(mod_path) = path.mod_path() else { + never!("resolver should always resolve lang item paths"); + return (self.err_ty(), None); + }; return self.resolve_variant_on_alias(ty, None, mod_path); }; @@ -1630,6 +1630,10 @@ impl<'a> InferenceContext<'a> { (ty, variant) } TypeNs::TypeAliasId(it) => { + let Some(mod_path) = path.mod_path() else { + never!("resolver should always resolve lang item paths"); + return (self.err_ty(), None); + }; let substs = path_ctx.substs_from_path_segment(it.into(), true, None); drop(ctx); let ty = self.db.ty(it.into()); diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs index afa1f6dcc8f4..651ec151d40c 100644 --- a/crates/hir/src/diagnostics.rs +++ b/crates/hir/src/diagnostics.rs @@ -570,10 +570,17 @@ impl AnyDiagnostic { source_map: &hir_def::expr_store::BodySourceMap, ) -> Option { let expr_syntax = |expr| { - source_map.expr_syntax(expr).inspect_err(|_| stdx::never!("synthetic syntax")).ok() + source_map + .expr_syntax(expr) + .inspect_err(|_| stdx::never!("inference diagnostic in desugared expr")) + .ok() + }; + let pat_syntax = |pat| { + source_map + .pat_syntax(pat) + .inspect_err(|_| stdx::never!("inference diagnostic in desugared pattern")) + .ok() }; - let pat_syntax = - |pat| source_map.pat_syntax(pat).inspect_err(|_| stdx::never!("synthetic syntax")).ok(); let expr_or_pat_syntax = |id| match id { ExprOrPatId::ExprId(expr) => expr_syntax(expr), ExprOrPatId::PatId(pat) => pat_syntax(pat), diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 7d855cf44986..13b161e59d94 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -753,7 +753,7 @@ impl Analysis { frange: FileRange, ) -> Cancellable> { let include_fixes = match &assist_config.allowed { - Some(it) => it.iter().any(|&it| it == AssistKind::QuickFix), + Some(it) => it.contains(&AssistKind::QuickFix), None => true, }; diff --git a/crates/intern/src/symbol/symbols.rs b/crates/intern/src/symbol/symbols.rs index 4841f4865915..a9ed1857de69 100644 --- a/crates/intern/src/symbol/symbols.rs +++ b/crates/intern/src/symbol/symbols.rs @@ -161,6 +161,7 @@ define_symbols! { bitxor_assign, bitxor, bool, + bootstrap, box_free, Box, boxed, @@ -525,4 +526,8 @@ define_symbols! { ignore_flyimport, ignore_flyimport_methods, ignore_methods, + position, + flags, + precision, + width, } diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index a0fb4a7d0fdb..7a139ea0c4ca 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -1664,6 +1664,7 @@ fn sysroot_to_crate_graph( vec![ CfgAtom::Flag(sym::debug_assertions.clone()), CfgAtom::Flag(sym::miri.clone()), + CfgAtom::Flag(sym::bootstrap.clone()), ], vec![CfgAtom::Flag(sym::test.clone())], ),