From d9b725abb02c5c648b847b0b4d13b213567df0e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 8 Aug 2025 13:16:07 +0200 Subject: [PATCH 1/8] Improve error output when a command fails in bootstrap --- src/bootstrap/src/utils/exec.rs | 165 ++++++++++++++++---------------- 1 file changed, 83 insertions(+), 82 deletions(-) diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 7527dff9cd843..03760faec690b 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -80,11 +80,21 @@ impl CommandFingerprint { /// Helper method to format both Command and BootstrapCommand as a short execution line, /// without all the other details (e.g. environment variables). pub fn format_short_cmd(&self) -> String { - let program = Path::new(&self.program); - let mut line = vec![program.file_name().unwrap().to_str().unwrap().to_owned()]; - line.extend(self.args.iter().map(|arg| arg.to_string_lossy().into_owned())); - line.extend(self.cwd.iter().map(|p| p.to_string_lossy().into_owned())); - line.join(" ") + use std::fmt::Write; + + let mut cmd = self.program.to_string_lossy().to_string(); + for arg in &self.args { + let arg = arg.to_string_lossy(); + if arg.contains(' ') { + write!(cmd, " '{arg}'").unwrap(); + } else { + write!(cmd, " {arg}").unwrap(); + } + } + if let Some(cwd) = &self.cwd { + write!(cmd, " [workdir={}]", cwd.to_string_lossy()).unwrap(); + } + cmd } } @@ -434,8 +444,8 @@ impl From for BootstrapCommand { enum CommandStatus { /// The command has started and finished with some status. Finished(ExitStatus), - /// It was not even possible to start the command. - DidNotStart, + /// It was not even possible to start the command or wait for it to finish. + DidNotStartOrFinish, } /// Create a new BootstrapCommand. This is a helper function to make command creation @@ -456,9 +466,9 @@ pub struct CommandOutput { impl CommandOutput { #[must_use] - pub fn did_not_start(stdout: OutputMode, stderr: OutputMode) -> Self { + pub fn not_finished(stdout: OutputMode, stderr: OutputMode) -> Self { Self { - status: CommandStatus::DidNotStart, + status: CommandStatus::DidNotStartOrFinish, stdout: match stdout { OutputMode::Print => None, OutputMode::Capture => Some(vec![]), @@ -489,7 +499,7 @@ impl CommandOutput { pub fn is_success(&self) -> bool { match self.status { CommandStatus::Finished(status) => status.success(), - CommandStatus::DidNotStart => false, + CommandStatus::DidNotStartOrFinish => false, } } @@ -501,7 +511,7 @@ impl CommandOutput { pub fn status(&self) -> Option { match self.status { CommandStatus::Finished(status) => Some(status), - CommandStatus::DidNotStart => None, + CommandStatus::DidNotStartOrFinish => None, } } @@ -745,25 +755,11 @@ impl ExecutionContext { self.start(command, stdout, stderr).wait_for_output(self) } - fn fail(&self, message: &str, output: CommandOutput) -> ! { - if self.is_verbose() { - println!("{message}"); - } else { - let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present()); - // If the command captures output, the user would not see any indication that - // it has failed. In this case, print a more verbose error, since to provide more - // context. - if stdout.is_some() || stderr.is_some() { - if let Some(stdout) = output.stdout_if_present().take_if(|s| !s.trim().is_empty()) { - println!("STDOUT:\n{stdout}\n"); - } - if let Some(stderr) = output.stderr_if_present().take_if(|s| !s.trim().is_empty()) { - println!("STDERR:\n{stderr}\n"); - } - println!("Command has failed. Rerun with -v to see more details."); - } else { - println!("Command has failed. Rerun with -v to see more details."); - } + fn fail(&self, message: &str) -> ! { + println!("{message}"); + + if !self.is_verbose() { + println!("Command has failed. Rerun with -v to see more details."); } exit!(1); } @@ -856,7 +852,7 @@ impl<'a> DeferredCommand<'a> { && command.should_cache { exec_ctx.command_cache.insert(fingerprint.clone(), output.clone()); - exec_ctx.profiler.record_execution(fingerprint.clone(), start_time); + exec_ctx.profiler.record_execution(fingerprint, start_time); } output @@ -872,6 +868,8 @@ impl<'a> DeferredCommand<'a> { executed_at: &'a std::panic::Location<'a>, exec_ctx: &ExecutionContext, ) -> CommandOutput { + use std::fmt::Write; + command.mark_as_executed(); let process = match process.take() { @@ -881,79 +879,82 @@ impl<'a> DeferredCommand<'a> { let created_at = command.get_created_location(); - let mut message = String::new(); + #[allow(clippy::enum_variant_names)] + enum FailureReason { + FailedAtRuntime(ExitStatus), + FailedToFinish(std::io::Error), + FailedToStart(std::io::Error), + } - let output = match process { + let (output, fail_reason) = match process { Ok(child) => match child.wait_with_output() { - Ok(result) if result.status.success() => { + Ok(output) if output.status.success() => { // Successful execution - CommandOutput::from_output(result, stdout, stderr) + (CommandOutput::from_output(output, stdout, stderr), None) } - Ok(result) => { - // Command ran but failed - use std::fmt::Write; - - writeln!( - message, - r#" -Command {command:?} did not execute successfully. -Expected success, got {} -Created at: {created_at} -Executed at: {executed_at}"#, - result.status, + Ok(output) => { + // Command started, but then it failed + let status = output.status; + ( + CommandOutput::from_output(output, stdout, stderr), + Some(FailureReason::FailedAtRuntime(status)), ) - .unwrap(); - - let output = CommandOutput::from_output(result, stdout, stderr); - - if stdout.captures() { - writeln!(message, "\nSTDOUT ----\n{}", output.stdout().trim()).unwrap(); - } - if stderr.captures() { - writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap(); - } - - output } Err(e) => { // Failed to wait for output - use std::fmt::Write; - - writeln!( - message, - "\n\nCommand {command:?} did not execute successfully.\ - \nIt was not possible to execute the command: {e:?}" + ( + CommandOutput::not_finished(stdout, stderr), + Some(FailureReason::FailedToFinish(e)), ) - .unwrap(); - - CommandOutput::did_not_start(stdout, stderr) } }, Err(e) => { // Failed to spawn the command - use std::fmt::Write; - - writeln!( - message, - "\n\nCommand {command:?} did not execute successfully.\ - \nIt was not possible to execute the command: {e:?}" - ) - .unwrap(); - - CommandOutput::did_not_start(stdout, stderr) + (CommandOutput::not_finished(stdout, stderr), Some(FailureReason::FailedToStart(e))) } }; - if !output.is_success() { + if let Some(fail_reason) = fail_reason { + let mut error_message = String::new(); + let command_str = if exec_ctx.is_verbose() { + format!("{command:?}") + } else { + command.fingerprint().format_short_cmd() + }; + let action = match fail_reason { + FailureReason::FailedAtRuntime(e) => { + format!("failed with exit code {}", e.code().unwrap_or(1)) + } + FailureReason::FailedToFinish(e) => { + format!("failed to finish: {e:?}") + } + FailureReason::FailedToStart(e) => { + format!("failed to start: {e:?}") + } + }; + writeln!( + error_message, + r#"Command `{command_str}` {action} +Created at: {created_at} +Executed at: {executed_at}"#, + ) + .unwrap(); + if stdout.captures() { + writeln!(error_message, "\n--- STDOUT vvv\n{}", output.stdout().trim()).unwrap(); + } + if stderr.captures() { + writeln!(error_message, "\n--- STDERR vvv\n{}", output.stderr().trim()).unwrap(); + } + match command.failure_behavior { BehaviorOnFailure::DelayFail => { if exec_ctx.fail_fast { - exec_ctx.fail(&message, output); + exec_ctx.fail(&error_message); } - exec_ctx.add_to_delay_failure(message); + exec_ctx.add_to_delay_failure(error_message); } BehaviorOnFailure::Exit => { - exec_ctx.fail(&message, output); + exec_ctx.fail(&error_message); } BehaviorOnFailure::Ignore => { // If failures are allowed, either the error has been printed already From dcc1605fba0ad04b8bc2d96d044f2ca3711b2219 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Fri, 8 Aug 2025 09:17:35 -0700 Subject: [PATCH 2/8] [win][arm64ec] Partial fix for raw-dylib-link-ordinal on Arm64EC --- tests/run-make/raw-dylib-link-ordinal/exporter.def | 2 +- tests/run-make/raw-dylib-link-ordinal/rmake.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/run-make/raw-dylib-link-ordinal/exporter.def b/tests/run-make/raw-dylib-link-ordinal/exporter.def index 5d87c580a54d5..0544e9f180332 100644 --- a/tests/run-make/raw-dylib-link-ordinal/exporter.def +++ b/tests/run-make/raw-dylib-link-ordinal/exporter.def @@ -1,5 +1,5 @@ LIBRARY exporter EXPORTS exported_function @13 NONAME - exported_variable @5 NONAME + exported_variable @5 NONAME DATA print_exported_variable @9 NONAME diff --git a/tests/run-make/raw-dylib-link-ordinal/rmake.rs b/tests/run-make/raw-dylib-link-ordinal/rmake.rs index 43274b9765bb1..b9254b167534b 100644 --- a/tests/run-make/raw-dylib-link-ordinal/rmake.rs +++ b/tests/run-make/raw-dylib-link-ordinal/rmake.rs @@ -11,7 +11,7 @@ //@ only-windows -use run_make_support::{cc, diff, is_windows_msvc, run, rustc}; +use run_make_support::{cc, diff, extra_c_flags, is_windows_msvc, run, rustc}; // NOTE: build_native_dynamic lib is not used, as the special `def` files // must be passed to the CC compiler. @@ -24,6 +24,7 @@ fn main() { cc().input("exporter.obj") .arg("exporter.def") .args(&["-link", "-dll", "-noimplib", "-out:exporter.dll"]) + .args(extra_c_flags()) .run(); } else { cc().arg("-v").arg("-c").out_exe("exporter.obj").input("exporter.c").run(); From 339be84d9dbe887ce704a5171e467b4fb363fbf4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 31 Jul 2025 17:14:39 +0200 Subject: [PATCH 3/8] Use new public libtest `ERROR_EXIT_CODE` constant in rustdoc --- src/librustdoc/doctest.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 35ace6566381b..73ce62cdcde6a 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -409,9 +409,7 @@ pub(crate) fn run_tests( // We ensure temp dir destructor is called. std::mem::drop(temp_dir); times.display_times(); - // FIXME(GuillaumeGomez): Uncomment the next line once #144297 has been merged. - // std::process::exit(test::ERROR_EXIT_CODE); - std::process::exit(101); + std::process::exit(test::ERROR_EXIT_CODE); } } From ad1113f87ef828b300ebb8fca397efd358580da3 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 9 Aug 2025 13:24:06 +0800 Subject: [PATCH 4/8] remove `P` --- compiler/rustc_ast/src/ast.rs | 331 +++++++++--------- compiler/rustc_ast/src/ast_traits.rs | 11 +- compiler/rustc_ast/src/attr/mod.rs | 5 +- .../rustc_ast/src/expand/autodiff_attrs.rs | 3 +- compiler/rustc_ast/src/format.rs | 3 +- compiler/rustc_ast/src/lib.rs | 1 - compiler/rustc_ast/src/mut_visit.rs | 19 +- compiler/rustc_ast/src/ptr.rs | 11 - compiler/rustc_ast/src/visit.rs | 29 +- compiler/rustc_ast_lowering/src/expr.rs | 17 +- compiler/rustc_ast_lowering/src/item.rs | 5 +- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_ast_lowering/src/pat.rs | 5 +- compiler/rustc_ast_lowering/src/path.rs | 2 +- .../rustc_ast_passes/src/ast_validation.rs | 3 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 3 +- .../rustc_ast_pretty/src/pprust/state/expr.rs | 13 +- .../rustc_ast_pretty/src/pprust/state/item.rs | 5 +- .../src/alloc_error_handler.rs | 3 +- compiler/rustc_builtin_macros/src/asm.rs | 13 +- compiler/rustc_builtin_macros/src/assert.rs | 15 +- .../src/assert/context.rs | 32 +- compiler/rustc_builtin_macros/src/autodiff.rs | 55 +-- compiler/rustc_builtin_macros/src/cfg_eval.rs | 15 +- .../rustc_builtin_macros/src/concat_bytes.rs | 3 +- .../src/deriving/cmp/partial_eq.rs | 9 +- .../src/deriving/debug.rs | 2 +- .../src/deriving/default.rs | 2 +- .../src/deriving/generic/mod.rs | 78 ++--- .../src/deriving/generic/ty.rs | 7 +- .../rustc_builtin_macros/src/deriving/mod.rs | 13 +- .../rustc_builtin_macros/src/edition_panic.rs | 5 +- compiler/rustc_builtin_macros/src/format.rs | 5 +- .../src/format_foreign.rs | 12 +- .../src/global_allocator.rs | 13 +- compiler/rustc_builtin_macros/src/iter.rs | 3 +- .../rustc_builtin_macros/src/pattern_type.rs | 16 +- .../src/proc_macro_harness.rs | 3 +- .../rustc_builtin_macros/src/source_util.rs | 5 +- compiler/rustc_builtin_macros/src/test.rs | 15 +- .../rustc_builtin_macros/src/test_harness.rs | 7 +- compiler/rustc_builtin_macros/src/util.rs | 11 +- compiler/rustc_expand/src/base.rs | 95 +++-- compiler/rustc_expand/src/build.rs | 218 ++++++------ compiler/rustc_expand/src/expand.rs | 122 ++++--- compiler/rustc_expand/src/module.rs | 3 +- compiler/rustc_expand/src/placeholders.rs | 68 ++-- compiler/rustc_expand/src/proc_macro.rs | 3 +- compiler/rustc_expand/src/stats.rs | 3 +- compiler/rustc_hir_typeck/src/pat.rs | 2 +- compiler/rustc_interface/src/passes.rs | 2 +- compiler/rustc_lint/src/early.rs | 3 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 2 +- compiler/rustc_parse/src/parser/asm.rs | 3 +- .../rustc_parse/src/parser/diagnostics.rs | 89 ++--- compiler/rustc_parse/src/parser/expr.rs | 206 +++++------ compiler/rustc_parse/src/parser/generics.rs | 6 +- compiler/rustc_parse/src/parser/item.rs | 41 +-- compiler/rustc_parse/src/parser/mod.rs | 31 +- .../rustc_parse/src/parser/nonterminal.rs | 16 +- compiler/rustc_parse/src/parser/pat.rs | 39 +-- compiler/rustc_parse/src/parser/path.rs | 9 +- compiler/rustc_parse/src/parser/stmt.rs | 27 +- compiler/rustc_parse/src/parser/tests.rs | 9 +- compiler/rustc_parse/src/parser/ty.rs | 51 +-- compiler/rustc_passes/src/input_stats.rs | 4 +- compiler/rustc_resolve/src/diagnostics.rs | 3 +- compiler/rustc_resolve/src/late.rs | 19 +- .../rustc_resolve/src/late/diagnostics.rs | 9 +- .../src/error_reporting/traits/suggestions.rs | 2 +- .../src/single_component_path_imports.rs | 3 +- .../clippy_lints/src/unnested_or_patterns.rs | 45 +-- .../clippy/clippy_utils/src/ast_utils/mod.rs | 9 +- .../crates/syntax-bridge/src/lib.rs | 8 +- src/tools/rustfmt/src/chains.rs | 6 +- src/tools/rustfmt/src/closures.rs | 4 +- src/tools/rustfmt/src/expr.rs | 6 +- src/tools/rustfmt/src/items.rs | 10 +- src/tools/rustfmt/src/macros.rs | 10 +- src/tools/rustfmt/src/matches.rs | 6 +- src/tools/rustfmt/src/modules.rs | 8 +- src/tools/rustfmt/src/overflow.rs | 4 +- .../rustfmt/src/parse/macros/lazy_static.rs | 3 +- src/tools/rustfmt/src/parse/macros/mod.rs | 14 +- src/tools/rustfmt/src/parse/parser.rs | 4 +- src/tools/rustfmt/src/patterns.rs | 13 +- src/tools/rustfmt/src/rewrite.rs | 3 +- src/tools/rustfmt/src/spanned.rs | 4 +- src/tools/rustfmt/src/types.rs | 5 +- src/tools/rustfmt/src/utils.rs | 6 +- src/tools/rustfmt/src/visitor.rs | 2 +- tests/ui-fulldeps/auxiliary/parser.rs | 3 +- tests/ui-fulldeps/pprust-expr-roundtrip.rs | 28 +- 93 files changed, 1043 insertions(+), 1056 deletions(-) delete mode 100644 compiler/rustc_ast/src/ptr.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index fdff18ffd4710..8160ed3cc46fa 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -35,7 +35,6 @@ use rustc_span::{ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, use thin_vec::{ThinVec, thin_vec}; pub use crate::format::*; -use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter}; use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream}; use crate::util::parser::{ExprPrecedence, Fixity}; @@ -225,7 +224,7 @@ pub struct PathSegment { /// `Some` means that parameter list is supplied (`Path`) /// but it can be empty (`Path<>`). /// `P` is used as a size optimization for the common case with no parameters. - pub args: Option>, + pub args: Option>, } // Succeeds if the path segment is arg-free and matches the given symbol. @@ -286,7 +285,7 @@ pub enum GenericArg { /// `'a` in `Foo<'a>`. Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime), /// `Bar` in `Foo`. - Type(P), + Type(Box), /// `1` in `Foo<1>`. Const(AnonConst), } @@ -328,15 +327,15 @@ impl AngleBracketedArg { } } -impl From for P { +impl From for Box { fn from(val: AngleBracketedArgs) -> Self { - P(GenericArgs::AngleBracketed(val)) + Box::new(GenericArgs::AngleBracketed(val)) } } -impl From for P { +impl From for Box { fn from(val: ParenthesizedArgs) -> Self { - P(GenericArgs::Parenthesized(val)) + Box::new(GenericArgs::Parenthesized(val)) } } @@ -350,7 +349,7 @@ pub struct ParenthesizedArgs { pub span: Span, /// `(A, B)` - pub inputs: ThinVec>, + pub inputs: ThinVec>, /// ```text /// Foo(A, B) -> C @@ -435,10 +434,10 @@ pub enum GenericParamKind { /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`). Lifetime, Type { - default: Option>, + default: Option>, }, Const { - ty: P, + ty: Box, /// Span of the whole parameter definition, including default. span: Span, /// Optional default value for the const generic param. @@ -526,7 +525,7 @@ pub struct WhereBoundPredicate { /// Any generics from a `for` binding. pub bound_generic_params: ThinVec, /// The type being bounded. - pub bounded_ty: P, + pub bounded_ty: Box, /// Trait and lifetime bounds (`Clone + Send + 'static`). #[visitable(extra = BoundKind::Bound)] pub bounds: GenericBounds, @@ -548,8 +547,8 @@ pub struct WhereRegionPredicate { /// E.g., `T = int`. #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub struct WhereEqPredicate { - pub lhs_ty: P, - pub rhs_ty: P, + pub lhs_ty: Box, + pub rhs_ty: Box, } #[derive(Clone, Encodable, Decodable, Debug, Walkable)] @@ -558,7 +557,7 @@ pub struct Crate { /// expansion placeholders or an unassigned value (`DUMMY_NODE_ID`) before that. pub id: NodeId, pub attrs: AttrVec, - pub items: ThinVec>, + pub items: ThinVec>, pub spans: ModSpans, pub is_placeholder: bool, } @@ -638,7 +637,7 @@ pub struct Pat { impl Pat { /// Attempt reparsing the pattern as a type. /// This is intended for use by diagnostics. - pub fn to_ty(&self) -> Option> { + pub fn to_ty(&self) -> Option> { let kind = match &self.kind { PatKind::Missing => unreachable!(), // In a type expression `_` is an inference variable. @@ -671,7 +670,7 @@ impl Pat { _ => return None, }; - Some(P(Ty { kind, id: self.id, span: self.span, tokens: None })) + Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None })) } /// Walk top-down and call `it` in each place where a pattern occurs @@ -764,8 +763,8 @@ impl Pat { } } -impl From> for Pat { - fn from(value: P) -> Self { +impl From> for Pat { + fn from(value: Box) -> Self { *value } } @@ -780,7 +779,7 @@ pub struct PatField { /// The identifier for the field. pub ident: Ident, /// The pattern the field is destructured to. - pub pat: P, + pub pat: Box, pub is_shorthand: bool, pub attrs: AttrVec, pub id: NodeId, @@ -865,44 +864,44 @@ pub enum PatKind { /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens /// during name resolution. - Ident(BindingMode, Ident, Option>), + Ident(BindingMode, Ident, Option>), /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`). - Struct(Option>, Path, ThinVec, PatFieldsRest), + Struct(Option>, Path, ThinVec, PatFieldsRest), /// A tuple struct/variant pattern (`Variant(x, y, .., z)`). - TupleStruct(Option>, Path, ThinVec>), + TupleStruct(Option>, Path, ThinVec>), /// An or-pattern `A | B | C`. /// Invariant: `pats.len() >= 2`. - Or(ThinVec>), + Or(ThinVec>), /// A possibly qualified path pattern. /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants /// or associated constants. Qualified path patterns `::B::C`/`::B::C` can /// only legally refer to associated constants. - Path(Option>, Path), + Path(Option>, Path), /// A tuple pattern (`(a, b)`). - Tuple(ThinVec>), + Tuple(ThinVec>), /// A `box` pattern. - Box(P), + Box(Box), /// A `deref` pattern (currently `deref!()` macro-based syntax). - Deref(P), + Deref(Box), /// A reference pattern (e.g., `&mut (a, b)`). - Ref(P, Mutability), + Ref(Box, Mutability), /// A literal, const block or path. - Expr(P), + Expr(Box), /// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`). - Range(Option>, Option>, Spanned), + Range(Option>, Option>, Spanned), /// A slice pattern `[a, b, c]`. - Slice(ThinVec>), + Slice(ThinVec>), /// A rest pattern `..`. /// @@ -922,13 +921,13 @@ pub enum PatKind { Never, /// A guard pattern (e.g., `x if guard(x)`). - Guard(P, P), + Guard(Box, Box), /// Parentheses in patterns used for grouping (i.e., `(PAT)`). - Paren(P), + Paren(Box), /// A macro pattern; pre-expansion. - MacCall(P), + MacCall(Box), /// Placeholder for a pattern that wasn't syntactically well formed in some way. Err(ErrorGuaranteed), @@ -1223,22 +1222,22 @@ impl Stmt { #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub enum StmtKind { /// A local (let) binding. - Let(P), + Let(Box), /// An item definition. - Item(P), + Item(Box), /// Expr without trailing semi-colon. - Expr(P), + Expr(Box), /// Expr with a trailing semi-colon. - Semi(P), + Semi(Box), /// Just a trailing semi-colon. Empty, /// Macro. - MacCall(P), + MacCall(Box), } #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub struct MacCallStmt { - pub mac: P, + pub mac: Box, pub style: MacStmtStyle, pub attrs: AttrVec, pub tokens: Option, @@ -1262,8 +1261,8 @@ pub enum MacStmtStyle { pub struct Local { pub id: NodeId, pub super_: Option, - pub pat: P, - pub ty: Option>, + pub pat: Box, + pub ty: Option>, pub kind: LocalKind, pub span: Span, pub colon_sp: Option, @@ -1278,10 +1277,10 @@ pub enum LocalKind { Decl, /// Local declaration with an initializer. /// Example: `let x = y;` - Init(P), + Init(Box), /// Local declaration with an initializer and an `else` clause. /// Example: `let Some(x) = y else { return };` - InitElse(P, P), + InitElse(Box, Box), } impl LocalKind { @@ -1315,11 +1314,11 @@ impl LocalKind { pub struct Arm { pub attrs: AttrVec, /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`. - pub pat: P, + pub pat: Box, /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`. - pub guard: Option>, + pub guard: Option>, /// Match arm body. Omitted if the pattern is a never pattern. - pub body: Option>, + pub body: Option>, pub span: Span, pub id: NodeId, pub is_placeholder: bool, @@ -1332,7 +1331,7 @@ pub struct ExprField { pub id: NodeId, pub span: Span, pub ident: Ident, - pub expr: P, + pub expr: Box, pub is_shorthand: bool, pub is_placeholder: bool, } @@ -1357,7 +1356,7 @@ pub enum UnsafeSource { #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub struct AnonConst { pub id: NodeId, - pub value: P, + pub value: Box, } /// An expression. @@ -1469,7 +1468,7 @@ impl Expr { } /// Attempts to reparse as `Ty` (for diagnostic purposes). - pub fn to_ty(&self) -> Option> { + pub fn to_ty(&self) -> Option> { let kind = match &self.kind { // Trivial conversions. ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()), @@ -1511,7 +1510,7 @@ impl Expr { _ => return None, }; - Some(P(Ty { kind, id: self.id, span: self.span, tokens: None })) + Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None })) } pub fn precedence(&self) -> ExprPrecedence { @@ -1632,8 +1631,8 @@ impl Expr { } } -impl From> for Expr { - fn from(value: P) -> Self { +impl From> for Expr { + fn from(value: Box) -> Self { *value } } @@ -1645,8 +1644,8 @@ pub struct Closure { pub constness: Const, pub coroutine_kind: Option, pub movability: Movability, - pub fn_decl: P, - pub body: P, + pub fn_decl: Box, + pub body: Box, /// The span of the declaration block: 'move |...| -> ...' pub fn_decl_span: Span, /// The span of the argument block `|...|` @@ -1677,9 +1676,9 @@ pub struct MethodCall { /// The method name and its generic arguments, e.g. `foo::`. pub seg: PathSegment, /// The receiver, e.g. `x`. - pub receiver: P, + pub receiver: Box, /// The arguments, e.g. `a, b, c`. - pub args: ThinVec>, + pub args: ThinVec>, /// The span of the function, without the dot and receiver e.g. `foo::(a, b, c)`. pub span: Span, @@ -1688,7 +1687,7 @@ pub struct MethodCall { #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub enum StructRest { /// `..x`. - Base(P), + Base(Box), /// `..`. Rest(Span), /// No trailing `..` or expression. @@ -1697,7 +1696,7 @@ pub enum StructRest { #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub struct StructExpr { - pub qself: Option>, + pub qself: Option>, pub path: Path, pub fields: ThinVec, pub rest: StructRest, @@ -1707,7 +1706,7 @@ pub struct StructExpr { #[derive(Clone, Encodable, Decodable, Debug)] pub enum ExprKind { /// An array (e.g, `[a, b, c, d]`). - Array(ThinVec>), + Array(ThinVec>), /// Allow anonymous constants from an inline `const` block. ConstBlock(AnonConst), /// A function call. @@ -1716,90 +1715,90 @@ pub enum ExprKind { /// and the second field is the list of arguments. /// This also represents calling the constructor of /// tuple-like ADTs such as tuple structs and enum variants. - Call(P, ThinVec>), + Call(Box, ThinVec>), /// A method call (e.g., `x.foo::(a, b, c)`). MethodCall(Box), /// A tuple (e.g., `(a, b, c, d)`). - Tup(ThinVec>), + Tup(ThinVec>), /// A binary operation (e.g., `a + b`, `a * b`). - Binary(BinOp, P, P), + Binary(BinOp, Box, Box), /// A unary operation (e.g., `!x`, `*x`). - Unary(UnOp, P), + Unary(UnOp, Box), /// A literal (e.g., `1`, `"foo"`). Lit(token::Lit), /// A cast (e.g., `foo as f64`). - Cast(P, P), + Cast(Box, Box), /// A type ascription (e.g., `builtin # type_ascribe(42, usize)`). /// /// Usually not written directly in user code but /// indirectly via the macro `type_ascribe!(...)`. - Type(P, P), + Type(Box, Box), /// A `let pat = expr` expression that is only semantically allowed in the condition /// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`). /// /// `Span` represents the whole `let pat = expr` statement. - Let(P, P, Span, Recovered), + Let(Box, Box, Span, Recovered), /// An `if` block, with an optional `else` block. /// /// `if expr { block } else { expr }` /// /// If present, the "else" expr is always `ExprKind::Block` (for `else`) or /// `ExprKind::If` (for `else if`). - If(P, P, Option>), + If(Box, Box, Option>), /// A while loop, with an optional label. /// /// `'label: while expr { block }` - While(P, P, Option