From 7b9d5b8758589db0cda82be95e43f41be48e9311 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Mar 2025 21:02:06 +0100 Subject: [PATCH 1/8] remove remnants of const_box feature --- library/alloc/src/boxed.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index e77caad65401b..4644e37f809c1 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1149,9 +1149,8 @@ impl Box { /// /// [memory layout]: self#memory-layout #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { + pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { Box(unsafe { Unique::new_unchecked(raw) }, alloc) } @@ -1203,9 +1202,8 @@ impl Box { /// [memory layout]: self#memory-layout #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const unsafe fn from_non_null_in(raw: NonNull, alloc: A) -> Self { + pub unsafe fn from_non_null_in(raw: NonNull, alloc: A) -> Self { // SAFETY: guaranteed by the caller. unsafe { Box::from_raw_in(raw.as_ptr(), alloc) } } @@ -1550,9 +1548,8 @@ impl Box { /// to call it as `Box::allocator(&b)` instead of `b.allocator()`. This /// is so that there is no conflict with a method on the inner type. #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn allocator(b: &Self) -> &A { + pub fn allocator(b: &Self) -> &A { &b.1 } @@ -1639,8 +1636,7 @@ impl Box { /// let bar = Pin::from(foo); /// ``` #[stable(feature = "box_into_pin", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] - pub const fn into_pin(boxed: Self) -> Pin + pub fn into_pin(boxed: Self) -> Pin where A: 'static, { From 8cab8e07bc94fb2fea8e1421d2d2e6de6398b69b Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Fri, 21 Mar 2025 17:34:45 -0700 Subject: [PATCH 2/8] Don't produce debug information for compiler-introduced-vars when desugaring assignments. An assignment such as (a, b) = (b, c); desugars to the HIR { let (lhs, lhs) = (b, c); a = lhs; b = lhs; }; The repeated `lhs` leads to multiple Locals assigned to the same DILocalVariable. Rather than attempting to fix that, get rid of the debug info for these bindings that don't even exist in the program to begin with. Fixes #138198 --- .../src/builder/matches/mod.rs | 58 ++++++++++++++----- tests/codegen/assign-desugar-debuginfo.rs | 18 ++++++ 2 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 tests/codegen/assign-desugar-debuginfo.rs diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index ea341b604e0be..cf216ff73ca27 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -13,13 +13,13 @@ use std::sync::Arc; use rustc_abi::VariantIdx; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_hir::{BindingMode, ByRef}; +use rustc_hir::{BindingMode, ByRef, LetStmt, LocalSource, Node}; use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::mir::{self, *}; use rustc_middle::thir::{self, *}; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty}; -use rustc_span::{BytePos, Pos, Span, Symbol}; +use rustc_span::{BytePos, Pos, Span, Symbol, sym}; use tracing::{debug, instrument}; use crate::builder::ForGuard::{self, OutsideGuard, RefWithinGuard}; @@ -2796,13 +2796,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { )))), }; let for_arm_body = self.local_decls.push(local); - self.var_debug_info.push(VarDebugInfo { - name, - source_info: debug_source_info, - value: VarDebugInfoContents::Place(for_arm_body.into()), - composite: None, - argument_index: None, - }); + if self.should_emit_debug_info_for_binding(name, var_id) { + self.var_debug_info.push(VarDebugInfo { + name, + source_info: debug_source_info, + value: VarDebugInfoContents::Place(for_arm_body.into()), + composite: None, + argument_index: None, + }); + } let locals = if has_guard.0 { let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> { // This variable isn't mutated but has a name, so has to be @@ -2815,13 +2817,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { BindingForm::RefForGuard, ))), }); - self.var_debug_info.push(VarDebugInfo { - name, - source_info: debug_source_info, - value: VarDebugInfoContents::Place(ref_for_guard.into()), - composite: None, - argument_index: None, - }); + if self.should_emit_debug_info_for_binding(name, var_id) { + self.var_debug_info.push(VarDebugInfo { + name, + source_info: debug_source_info, + value: VarDebugInfoContents::Place(ref_for_guard.into()), + composite: None, + argument_index: None, + }); + } LocalsForNode::ForGuard { ref_for_guard, for_arm_body } } else { LocalsForNode::One(for_arm_body) @@ -2829,4 +2833,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!(?locals); self.var_indices.insert(var_id, locals); } + + /// Some bindings are introduced when producing HIR from the AST and don't + /// actually exist in the source. Skip producing debug info for those when + /// we can recognize them. + fn should_emit_debug_info_for_binding(&self, name: Symbol, var_id: LocalVarId) -> bool { + // For now we only recognize the output of desugaring assigns. + if name != sym::lhs { + return true; + } + + let tcx = self.tcx; + for (_, node) in tcx.hir_parent_iter(var_id.0) { + // FIXME(khuey) at what point is it safe to bail on the iterator? + // Can we stop at the first non-Pat node? + if matches!(node, Node::LetStmt(&LetStmt { source: LocalSource::AssignDesugar(_), .. })) + { + return false; + } + } + + true + } } diff --git a/tests/codegen/assign-desugar-debuginfo.rs b/tests/codegen/assign-desugar-debuginfo.rs new file mode 100644 index 0000000000000..77ee8758b3b3b --- /dev/null +++ b/tests/codegen/assign-desugar-debuginfo.rs @@ -0,0 +1,18 @@ +//@ compile-flags: -g -Zmir-opt-level=0 + +#![crate_type = "lib"] + +#[inline(never)] +fn swizzle(a: u32, b: u32, c: u32) -> (u32, (u32, u32)) { + (b, (c, a)) +} + +pub fn work() { + let mut a = 1; + let mut b = 2; + let mut c = 3; + (a, (b, c)) = swizzle(a, b, c); + println!("{a} {b} {c}"); +} + +// CHECK-NOT: !DILocalVariable(name: "lhs", From 83145a674444c15e61f1b4fb7043e8cdc4a62ea3 Mon Sep 17 00:00:00 2001 From: dianne Date: Fri, 21 Mar 2025 19:52:53 -0700 Subject: [PATCH 3/8] match lowering cleanup: `non_scalar_compare` is only for `&str` Since array and slice constants are now lowered to array and slice patterns, `non_scalar_compare` was only called for string comparisons. This specializes it to strings, renames it, and removes the unused array-unsizing logic. This also updates some outdated doc comments. --- compiler/rustc_middle/src/thir.rs | 6 +- .../src/builder/matches/mod.rs | 4 +- .../src/builder/matches/test.rs | 108 +++--------------- 3 files changed, 24 insertions(+), 94 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index bbcd509c55869..6783bbf8bf42f 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -800,9 +800,9 @@ pub enum PatKind<'tcx> { }, /// One of the following: - /// * `&str`/`&[u8]` (represented as a valtree), which will be handled as a string/slice pattern - /// and thus exhaustiveness checking will detect if you use the same string/slice twice in - /// different patterns. + /// * `&str` (represented as a valtree), which will be handled as a string pattern and thus + /// exhaustiveness checking will detect if you use the same string twice in different + /// patterns. /// * integer, bool, char or float (represented as a valtree), which will be handled by /// exhaustiveness to cover exactly its own value, similar to `&str`, but these values are /// much simpler. diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index ea341b604e0be..710538ef4b867 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1326,8 +1326,8 @@ enum TestKind<'tcx> { Eq { value: Const<'tcx>, // Integer types are handled by `SwitchInt`, and constants with ADT - // types are converted back into patterns, so this can only be `&str`, - // `&[T]`, `f32` or `f64`. + // types and `&[T]` types are converted back into patterns, so this can + // only be `&str`, `f32` or `f64`. ty: Ty<'tcx>, }, diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index e5d61bc9e556a..7ef9e48326f63 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -11,7 +11,6 @@ use std::sync::Arc; use rustc_data_structures::fx::FxIndexMap; use rustc_hir::{LangItem, RangeEnd}; use rustc_middle::mir::*; -use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; @@ -178,21 +177,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { _ => {} } + assert_eq!(expect_ty, ty); if !ty.is_scalar() { // Use `PartialEq::eq` instead of `BinOp::Eq` // (the binop can only handle primitives) - self.non_scalar_compare( + // Make sure that we do *not* call any user-defined code here. + // The only type that can end up here is string literals, which have their + // comparison defined in `core`. + // (Interestingly this means that exhaustiveness analysis relies, for soundness, + // on the `PartialEq` impl for `str` to b correct!) + match *ty.kind() { + ty::Ref(_, deref_ty, _) if deref_ty == self.tcx.types.str_ => {} + _ => { + span_bug!(source_info.span, "invalid type for non-scalar compare: {ty}") + } + }; + self.string_compare( block, success_block, fail_block, source_info, expect, - expect_ty, Operand::Copy(place), - ty, ); } else { - assert_eq!(expect_ty, ty); self.compare( block, success_block, @@ -370,97 +378,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); } - /// Compare two values using `::eq`. - /// If the values are already references, just call it directly, otherwise - /// take a reference to the values first and then call it. - fn non_scalar_compare( + /// Compare two values of type `&str` using `::eq`. + fn string_compare( &mut self, block: BasicBlock, success_block: BasicBlock, fail_block: BasicBlock, source_info: SourceInfo, - mut expect: Operand<'tcx>, - expect_ty: Ty<'tcx>, - mut val: Operand<'tcx>, - mut ty: Ty<'tcx>, + expect: Operand<'tcx>, + val: Operand<'tcx>, ) { - // If we're using `b"..."` as a pattern, we need to insert an - // unsizing coercion, as the byte string has the type `&[u8; N]`. - // - // We want to do this even when the scrutinee is a reference to an - // array, so we can call `<[u8]>::eq` rather than having to find an - // `<[u8; N]>::eq`. - let unsize = |ty: Ty<'tcx>| match ty.kind() { - ty::Ref(region, rty, _) => match rty.kind() { - ty::Array(inner_ty, n) => Some((region, inner_ty, n)), - _ => None, - }, - _ => None, - }; - let opt_ref_ty = unsize(ty); - let opt_ref_test_ty = unsize(expect_ty); - match (opt_ref_ty, opt_ref_test_ty) { - // nothing to do, neither is an array - (None, None) => {} - (Some((region, elem_ty, _)), _) | (None, Some((region, elem_ty, _))) => { - let tcx = self.tcx; - // make both a slice - ty = Ty::new_imm_ref(tcx, *region, Ty::new_slice(tcx, *elem_ty)); - if opt_ref_ty.is_some() { - let temp = self.temp(ty, source_info.span); - self.cfg.push_assign( - block, - source_info, - temp, - Rvalue::Cast( - CastKind::PointerCoercion( - PointerCoercion::Unsize, - CoercionSource::Implicit, - ), - val, - ty, - ), - ); - val = Operand::Copy(temp); - } - if opt_ref_test_ty.is_some() { - let slice = self.temp(ty, source_info.span); - self.cfg.push_assign( - block, - source_info, - slice, - Rvalue::Cast( - CastKind::PointerCoercion( - PointerCoercion::Unsize, - CoercionSource::Implicit, - ), - expect, - ty, - ), - ); - expect = Operand::Move(slice); - } - } - } - - // Figure out the type on which we are calling `PartialEq`. This involves an extra wrapping - // reference: we can only compare two `&T`, and then compare_ty will be `T`. - // Make sure that we do *not* call any user-defined code here. - // The only types that can end up here are string and byte literals, - // which have their comparison defined in `core`. - // (Interestingly this means that exhaustiveness analysis relies, for soundness, - // on the `PartialEq` impls for `str` and `[u8]` to b correct!) - let compare_ty = match *ty.kind() { - ty::Ref(_, deref_ty, _) - if deref_ty == self.tcx.types.str_ || deref_ty != self.tcx.types.u8 => - { - deref_ty - } - _ => span_bug!(source_info.span, "invalid type for non-scalar compare: {}", ty), - }; - + let str_ty = self.tcx.types.str_; let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span)); - let method = trait_method(self.tcx, eq_def_id, sym::eq, [compare_ty, compare_ty]); + let method = trait_method(self.tcx, eq_def_id, sym::eq, [str_ty, str_ty]); let bool_ty = self.tcx.types.bool; let eq_result = self.temp(bool_ty, source_info.span); From c25e4bfe68ff3d313398cdbf0a459f82c37d1bb7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 22 Mar 2025 18:09:01 +0300 Subject: [PATCH 4/8] resolve: Avoid some unstable iteration 3 --- compiler/rustc_resolve/src/late.rs | 13 ++++++------- compiler/rustc_resolve/src/late/diagnostics.rs | 5 ----- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 6056a69ee71f6..1eff824aa624e 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -272,7 +272,7 @@ impl RibKind<'_> { /// resolving, the name is looked up from inside out. #[derive(Debug)] pub(crate) struct Rib<'ra, R = Res> { - pub bindings: FxHashMap, + pub bindings: FxIndexMap, pub patterns_with_skipped_bindings: UnordMap)>>, pub kind: RibKind<'ra>, } @@ -1642,8 +1642,8 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Allow all following defaults to refer to this type parameter. let i = &Ident::with_dummy_span(param.ident.name); - forward_ty_ban_rib.bindings.remove(i); - forward_ty_ban_rib_const_param_ty.bindings.remove(i); + forward_ty_ban_rib.bindings.swap_remove(i); + forward_ty_ban_rib_const_param_ty.bindings.swap_remove(i); } GenericParamKind::Const { ref ty, kw_span: _, ref default } => { // Const parameters can't have param bounds. @@ -1678,8 +1678,8 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Allow all following defaults to refer to this const parameter. let i = &Ident::with_dummy_span(param.ident.name); - forward_const_ban_rib.bindings.remove(i); - forward_const_ban_rib_const_param_ty.bindings.remove(i); + forward_const_ban_rib.bindings.swap_remove(i); + forward_const_ban_rib_const_param_ty.bindings.swap_remove(i); } } } @@ -2888,7 +2888,6 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { break; } - #[allow(rustc::potential_query_instability)] // FIXME seen_bindings .extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span))); } @@ -4003,7 +4002,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } } - fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut FxHashMap { + fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut FxIndexMap { &mut self.ribs[ns].last_mut().unwrap().bindings } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 3d666055a94fb..6d95c02c55fc2 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -830,7 +830,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { if let Some(rib) = &self.last_block_rib && let RibKind::Normal = rib.kind { - #[allow(rustc::potential_query_instability)] // FIXME for (ident, &res) in &rib.bindings { if let Res::Local(_) = res && path.len() == 1 @@ -1019,7 +1018,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { if let Some(err_code) = err.code { if err_code == E0425 { for label_rib in &self.label_ribs { - #[allow(rustc::potential_query_instability)] // FIXME for (label_ident, node_id) in &label_rib.bindings { let ident = path.last().unwrap().ident; if format!("'{ident}") == label_ident.to_string() { @@ -2265,7 +2263,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { }; // Locals and type parameters - #[allow(rustc::potential_query_instability)] // FIXME for (ident, &res) in &rib.bindings { if filter_fn(res) && ident.span.ctxt() == rib_ctxt { names.push(TypoSuggestion::typo_from_ident(*ident, res)); @@ -2793,7 +2790,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let within_scope = self.is_label_valid_from_rib(rib_index); let rib = &self.label_ribs[rib_index]; - #[allow(rustc::potential_query_instability)] // FIXME let names = rib .bindings .iter() @@ -2805,7 +2801,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // Upon finding a similar name, get the ident that it was from - the span // contained within helps make a useful diagnostic. In addition, determine // whether this candidate is within scope. - #[allow(rustc::potential_query_instability)] // FIXME let (ident, _) = rib.bindings.iter().find(|(ident, _)| ident.name == symbol).unwrap(); (*ident, within_scope) }) From 7210df1a9ac3cec2e925012bcc9190c13b5a2402 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 23 Mar 2025 18:45:34 +0100 Subject: [PATCH 5/8] Rework `--print` options documentation --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/command-line-arguments.md | 53 +---- .../command-line-arguments/print-options.md | 212 ++++++++++++++++++ 3 files changed, 214 insertions(+), 52 deletions(-) create mode 100644 src/doc/rustc/src/command-line-arguments/print-options.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 542ee9fffce3a..e258b0a76ffd9 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -2,6 +2,7 @@ - [What is rustc?](what-is-rustc.md) - [Command-line Arguments](command-line-arguments.md) + - [Print Options](command-line-arguments/print-options.md) - [Codegen Options](codegen-options/index.md) - [Jobserver](jobserver.md) - [Lints](lints/index.md) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 9dd2e7de1b330..b704cee705b05 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -247,58 +247,7 @@ types to stdout at the same time will result in an error. ## `--print`: print compiler information -This flag prints out various information about the compiler. This flag may be -specified multiple times, and the information is printed in the order the -flags are specified. Specifying a `--print` flag will usually disable the -[`--emit`](#option-emit) step and will only print the requested information. -The valid types of print values are: - -- `crate-name` — The name of the crate. -- `file-names` — The names of the files created by the `link` emit kind. -- `sysroot` — Path to the sysroot. -- `target-libdir` — Path to the target libdir. -- `host-tuple` — The target-tuple string of the host compiler (e.g. `x86_64-unknown-linux-gnu`) -- `cfg` — List of cfg values. See [conditional compilation] for more - information about cfg values. -- `target-list` — List of known targets. The target may be selected with the - `--target` flag. -- `target-cpus` — List of available CPU values for the current target. The - target CPU may be selected with the [`-C target-cpu=val` - flag](codegen-options/index.md#target-cpu). -- `target-features` — List of available target features for the current - target. Target features may be enabled with the [`-C target-feature=val` - flag](codegen-options/index.md#target-feature). This flag is unsafe. See - [known issues](targets/known-issues.md) for more details. -- `relocation-models` — List of relocation models. Relocation models may be - selected with the [`-C relocation-model=val` - flag](codegen-options/index.md#relocation-model). -- `code-models` — List of code models. Code models may be selected with the - [`-C code-model=val` flag](codegen-options/index.md#code-model). -- `tls-models` — List of Thread Local Storage models supported. The model may - be selected with the `-Z tls-model=val` flag. -- `native-static-libs` — This may be used when creating a `staticlib` crate - type. If this is the only flag, it will perform a full compilation and - include a diagnostic note that indicates the linker flags to use when - linking the resulting static library. The note starts with the text - `native-static-libs:` to make it easier to fetch the output. -- `link-args` — This flag does not disable the `--emit` step. When linking, - this flag causes `rustc` to print the full linker invocation in a - human-readable form. This can be useful when debugging linker options. The - exact format of this debugging output is not a stable guarantee, other than - that it will include the linker executable and the text of each command-line - argument passed to the linker. -- `deployment-target` — The currently selected [deployment target] (or minimum OS version) - for the selected Apple platform target. This value can be used or passed along to other - components alongside a Rust build that need this information, such as C compilers. - This returns rustc's minimum supported deployment target if no `*_DEPLOYMENT_TARGET` variable - is present in the environment, or otherwise returns the variable's parsed value. - -A filepath may optionally be specified for each requested information kind, in -the format `--print KIND=PATH`, just like for `--emit`. When a path is -specified, information will be written there instead of to stdout. - -[conditional compilation]: ../reference/conditional-compilation.html -[deployment target]: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/cross_development/Configuring/configuring.html +This flag will allow you to set [print options](command-line-arguments/print-options.md). ## `-g`: include debug information diff --git a/src/doc/rustc/src/command-line-arguments/print-options.md b/src/doc/rustc/src/command-line-arguments/print-options.md new file mode 100644 index 0000000000000..1f33e91e5d1b6 --- /dev/null +++ b/src/doc/rustc/src/command-line-arguments/print-options.md @@ -0,0 +1,212 @@ +# Print Options + +All of these options are passed to `rustc` via the `--print` flag. + +Those options prints out various information about the compiler. Multiple options can be +specified, and the information is printed in the order the options are specified. + +Specifying an option will usually disable the [`--emit`](../command-line-arguments.md#option-emit) +step and will only print the requested information. + +A filepath may optionally be specified for each requested information kind, in the format +`--print KIND=PATH`, just like for `--emit`. When a path is specified, information will be +written there instead of to stdout. + +## `crate-name` + +The name of the crate. + +Generally coming from either from the `#![crate_name = "..."]` attribute, +[`--crate-name` flag](../command-line-arguments.md#option-crate-name) or the filename. + +Example: + +```bash +$ rustc --print crate-name --crate-name my_crate a.rs +my_crate +``` + +## `file-names` + +The names of the files created by the `link` emit kind. + +## `sysroot` + +Abosulte path to the sysroot. + +Example (with rustup and the stable toolchain): + +```bash +$ rustc --print sysroot a.rs +/home/[REDACTED]/.rustup/toolchains/stable-x86_64-unknown-linux-gnu +``` + +## `target-libdir` + +Path to the target libdir. + +Example (with rustup and the stable toolchain): + +```bash +$ rustc --print target-libdir a.rs +/home/[REDACTED]/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib +``` + +## `host-tuple` + +The target-tuple string of the host compiler. + +Example: + +```bash +$ rustc --print host-tuple a.rs +x86_64-unknown-linux-gnu +``` + +Example with the `--target` flag: + +```bash +$ rustc --print host-tuple --target "armv7-unknown-linux-gnueabihf" a.rs +x86_64-unknown-linux-gnu +``` + +## `cfg` + +List of cfg values. See [conditional compilation] for more information about cfg values. + +Example (for `x86_64-unknown-linux-gnu`): + +```bash +$ rustc --print cfg a.rs +debug_assertions +panic="unwind" +target_abi="" +target_arch="x86_64" +target_endian="little" +target_env="gnu" +target_family="unix" +target_feature="fxsr" +target_feature="sse" +target_feature="sse2" +target_has_atomic="16" +target_has_atomic="32" +target_has_atomic="64" +target_has_atomic="8" +target_has_atomic="ptr" +target_os="linux" +target_pointer_width="64" +target_vendor="unknown" +unix +``` + +## `target-list` + +List of known targets. The target may be selected with the `--target` flag. + +## `target-cpus` + +List of available CPU values for the current target. The target CPU may be selected with +the [`-C target-cpu=val` flag](../codegen-options/index.md#target-cpu). + +## `target-features` + +List of available target features for the *current target*. + +Target features may be enabled with the **unsafe** +[`-C target-feature=val` flag](../codegen-options/index.md#target-feature). + +See [known issues](../targets/known-issues.md) for more details. + +## `relocation-models` + +List of relocation models. Relocation models may be selected with the +[`-C relocation-model=val` flag](../codegen-options/index.md#relocation-model). + +Example: + +```bash +$ rustc --print relocation-models a.rs +Available relocation models: + static + pic + pie + dynamic-no-pic + ropi + rwpi + ropi-rwpi + default +``` + +## `code-models` + +List of code models. Code models may be selected with the +[`-C code-model=val` flag](../codegen-options/index.md#code-model). + +Example: + +```bash +$ rustc --print code-models a.rs +Available code models: + tiny + small + kernel + medium + large +``` + +## `tls-models` + +List of Thread Local Storage models supported. The model may be selected with the +`-Z tls-model=val` flag. + +Example: + +```bash +$ rustc --print tls-models a.rs +Available TLS models: + global-dynamic + local-dynamic + initial-exec + local-exec + emulated +``` + +## `native-static-libs` + +This may be used when creating a `staticlib` crate type. + +If this is the only flag, it will perform a full compilation and include a diagnostic note +that indicates the linker flags to use when linking the resulting static library. + +The note starts with the text `native-static-libs:` to make it easier to fetch the output. + +Example: + +```bash +$ rustc --print native-static-libs --crate-type staticlib a.rs +note: Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms. + +note: native-static-libs: -lgcc_s -lutil [REDACTED] -lpthread -lm -ldl -lc +``` + +## `link-args` + +This flag does not disable the `--emit` step. This can be useful when debugging linker options. + +When linking, this flag causes `rustc` to print the full linker invocation in a human-readable +form. The exact format of this debugging output is not a stable guarantee, other than that it +will include the linker executable and the text of each command-line argument passed to the +linker. + +## `deployment-target` + +The currently selected [deployment target] (or minimum OS version) for the selected Apple +platform target. + +This value can be used or passed along to other components alongside a Rust build that need +this information, such as C compilers. This returns rustc's minimum supported deployment target +if no `*_DEPLOYMENT_TARGET` variable is present in the environment, or otherwise returns the +variable's parsed value. + +[conditional compilation]: ../../reference/conditional-compilation.html +[deployment target]: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/cross_development/Configuring/configuring.html From 0cd1d516aee85608a695d0376cdef059cc50e00a Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Tue, 18 Mar 2025 18:09:22 +0530 Subject: [PATCH 6/8] std: fs: uefi: Implement canonicalize - Should be same as absolute in UEFI since there are no symlinks. - Also each absolute path representation should be unique according to the UEFI specification. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 54acd4c27b334..f7c33b7c40f0a 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -315,8 +315,8 @@ pub fn lstat(_p: &Path) -> io::Result { unsupported() } -pub fn canonicalize(_p: &Path) -> io::Result { - unsupported() +pub fn canonicalize(p: &Path) -> io::Result { + crate::path::absolute(p) } pub fn copy(_from: &Path, _to: &Path) -> io::Result { From fc0cf52e28cdbc5de45b650797365c91d0c8de76 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Tue, 18 Mar 2025 18:11:18 +0530 Subject: [PATCH 7/8] std: fs: uefi: Make lstat call stat - UEFI does not have symlinks. So lstat and stat should behave the same. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index f7c33b7c40f0a..e1d61aaa309ea 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -311,8 +311,8 @@ pub fn stat(_p: &Path) -> io::Result { unsupported() } -pub fn lstat(_p: &Path) -> io::Result { - unsupported() +pub fn lstat(p: &Path) -> io::Result { + stat(p) } pub fn canonicalize(p: &Path) -> io::Result { From 021d23b64ee58b6d4d7f8803729182ad02a567c2 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Tue, 18 Mar 2025 18:26:00 +0530 Subject: [PATCH 8/8] std: fs: uefi: Implement OpenOptions UEFI does not have specific modes for create_new, truncate and append. So those need to to be simulated after opening the file. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 66 +++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index e1d61aaa309ea..d6ae86bd3d26e 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -1,3 +1,5 @@ +use r_efi::protocols::file; + use crate::ffi::OsString; use crate::fmt; use crate::hash::Hash; @@ -22,7 +24,12 @@ pub struct ReadDir(!); pub struct DirEntry(!); #[derive(Clone, Debug)] -pub struct OpenOptions {} +pub struct OpenOptions { + mode: u64, + append: bool, + truncate: bool, + create_new: bool, +} #[derive(Copy, Clone, Debug, Default)] pub struct FileTimes {} @@ -141,15 +148,58 @@ impl DirEntry { impl OpenOptions { pub fn new() -> OpenOptions { - OpenOptions {} + OpenOptions { mode: 0, append: false, create_new: false, truncate: false } + } + + pub fn read(&mut self, read: bool) { + if read { + self.mode |= file::MODE_READ; + } else { + self.mode &= !file::MODE_READ; + } + } + + pub fn write(&mut self, write: bool) { + if write { + // Valid Combinations: Read, Read/Write, Read/Write/Create + self.read(true); + self.mode |= file::MODE_WRITE; + } else { + self.mode &= !file::MODE_WRITE; + } + } + + pub fn append(&mut self, append: bool) { + // Docs state that `.write(true).append(true)` has the same effect as `.append(true)` + if append { + self.write(true); + } + self.append = append; + } + + pub fn truncate(&mut self, truncate: bool) { + self.truncate = truncate; + } + + pub fn create(&mut self, create: bool) { + if create { + self.mode |= file::MODE_CREATE; + } else { + self.mode &= !file::MODE_CREATE; + } + } + + pub fn create_new(&mut self, create_new: bool) { + self.create_new = create_new; } - pub fn read(&mut self, _read: bool) {} - pub fn write(&mut self, _write: bool) {} - pub fn append(&mut self, _append: bool) {} - pub fn truncate(&mut self, _truncate: bool) {} - pub fn create(&mut self, _create: bool) {} - pub fn create_new(&mut self, _create_new: bool) {} + #[expect(dead_code)] + const fn is_mode_valid(&self) -> bool { + // Valid Combinations: Read, Read/Write, Read/Write/Create + self.mode == file::MODE_READ + || self.mode == (file::MODE_READ | file::MODE_WRITE) + || self.mode == (file::MODE_READ | file::MODE_WRITE | file::MODE_CREATE) + } } impl File {