diff --git a/Cargo.toml b/Cargo.toml index f7e3ae51df..6895dcc3c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ authors = ["rust-analyzer team"] [profile.dev] # Disabling debug info speeds up builds a bunch, # and we don't rely on it for debugging that much. -debug = 0 +debug = 1 [profile.dev.package] # These speed up local tests. diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs index 340e95dbc2..f58228c45f 100644 --- a/crates/hir-def/src/body/lower.rs +++ b/crates/hir-def/src/body/lower.rs @@ -1869,42 +1869,45 @@ impl ExprCollector<'_> { ) -> ExprId { match count { Some(FormatCount::Literal(n)) => { - match LangItem::FormatCount.ty_rel_path(self.db, self.krate, name![Is]) { - Some(count_is) => { - let count_is = self.alloc_expr_desugared(Expr::Path(count_is)); - let args = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( - *n as u128, - Some(BuiltinUint::Usize), - ))); - self.alloc_expr_desugared(Expr::Call { - callee: count_is, - args: Box::new([args]), - is_assignee_expr: false, - }) - } - None => self.missing_expr(), - } + let args = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( + *n as u128, + Some(BuiltinUint::Usize), + ))); + let count_is = + match LangItem::FormatCount.ty_rel_path(self.db, self.krate, name![Is]) { + Some(count_is) => self.alloc_expr_desugared(Expr::Path(count_is)), + None => self.missing_expr(), + }; + self.alloc_expr_desugared(Expr::Call { + callee: count_is, + args: Box::new([args]), + is_assignee_expr: false, + }) } Some(FormatCount::Argument(arg)) => { if let Ok(arg_index) = arg.index { let (i, _) = argmap.insert_full((arg_index, ArgumentType::Usize)); - match LangItem::FormatCount.ty_rel_path(self.db, self.krate, name![Param]) { - Some(count_param) => { - let count_param = self.alloc_expr_desugared(Expr::Path(count_param)); - let args = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( - i as u128, - Some(BuiltinUint::Usize), - ))); - self.alloc_expr_desugared(Expr::Call { - callee: count_param, - args: Box::new([args]), - is_assignee_expr: false, - }) - } + let args = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( + i as u128, + Some(BuiltinUint::Usize), + ))); + let count_param = match LangItem::FormatCount.ty_rel_path( + self.db, + self.krate, + name![Param], + ) { + Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), None => self.missing_expr(), - } + }; + self.alloc_expr_desugared(Expr::Call { + callee: count_param, + args: Box::new([args]), + is_assignee_expr: false, + }) } else { + // FIXME: This drops arg causing it to potentially not be resolved/type checked + // when typing? self.missing_expr() } } @@ -1925,7 +1928,8 @@ impl ExprCollector<'_> { fn make_argument(&mut self, arg: ExprId, ty: ArgumentType) -> ExprId { use ArgumentType::*; use FormatTrait::*; - match LangItem::FormatArgument.ty_rel_path( + + let new_fn = match LangItem::FormatArgument.ty_rel_path( self.db, self.krate, match ty { @@ -1941,16 +1945,14 @@ impl ExprCollector<'_> { Usize => name![from_usize], }, ) { - Some(new_fn) => { - let new_fn = self.alloc_expr_desugared(Expr::Path(new_fn)); - self.alloc_expr_desugared(Expr::Call { - callee: new_fn, - args: Box::new([arg]), - is_assignee_expr: false, - }) - } + Some(new_fn) => self.alloc_expr_desugared(Expr::Path(new_fn)), None => self.missing_expr(), - } + }; + self.alloc_expr_desugared(Expr::Call { + callee: new_fn, + args: Box::new([arg]), + is_assignee_expr: false, + }) } // endregion: format } diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram index e1765b25fd..8a775dd874 100644 --- a/crates/syntax/rust.ungram +++ b/crates/syntax/rust.ungram @@ -391,6 +391,7 @@ FormatArgsExpr = FormatArgsArg = (Name '=')? Expr +# MacroCallExpr MacroExpr = MacroCall diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs index 8ae3a56227..3018f2c133 100644 --- a/crates/test-utils/src/minicore.rs +++ b/crates/test-utils/src/minicore.rs @@ -913,6 +913,7 @@ pub mod fmt { } mod rt { + use super::*; extern "C" { type Opaque; @@ -930,8 +931,8 @@ pub mod fmt { unsafe { Argument { formatter: transmute(f), value: transmute(x) } } } - pub fn new_display<'b, T: Display>(x: &'b T) -> Argument<'_> { - Self::new(x, Display::fmt) + pub fn new_display<'b, T: crate::fmt::Display>(x: &'b T) -> Argument<'_> { + Self::new(x, crate::fmt::Display::fmt) } } @@ -968,7 +969,9 @@ pub mod fmt { flags: u32, precision: Count, width: Count, - ) -> Self; + ) -> Self { + Placeholder { position, fill, align, flags, precision, width } + } } #[lang = "format_unsafe_arg"] @@ -1007,6 +1010,14 @@ pub mod fmt { ) -> Arguments<'a> { Arguments { pieces, fmt: Some(fmt), args } } + + pub const fn as_str(&self) -> Option<&'static str> { + match (self.pieces, self.args) { + ([], []) => Some(""), + ([s], []) => Some(s), + _ => None, + } + } } // region:derive @@ -1156,8 +1167,8 @@ pub mod pin { pointer: P, } impl

Pin

{ - pub fn new(_pointer: P) -> Pin

{ - loop {} + pub fn new(pointer: P) -> Pin

{ + Pin { pointer } } } // region:deref @@ -1382,12 +1393,23 @@ mod panic { mod panicking { #[rustc_const_panic_str] // enforce a &&str argument in const-check and hook this by const-eval - pub const fn panic_display(x: &T) -> ! { - panic_fmt(format_args!("{}", *x)); + pub const fn panic_display(x: &T) -> ! { + panic_fmt(crate::format_args!("{}", *x)); + } + + // This function is used instead of panic_fmt in const eval. + #[lang = "const_panic_fmt"] + pub const fn const_panic_fmt(fmt: crate::fmt::Arguments<'_>) -> ! { + if let Some(msg) = fmt.as_str() { + // The panic_display function is hooked by const eval. + panic_display(&msg); + } else { + loop {} + } } #[lang = "panic_fmt"] // needed for const-evaluated panics - pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { + pub const fn panic_fmt(fmt: crate::fmt::Arguments<'_>) -> ! { loop {} }