Skip to content

Rollup of 12 pull requests #142574

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Jun 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
c85760c
Fix Debug for Location.
m-ou-se Jun 11, 2025
5b50e0b
Add support for snapshot tests with insta
Kobzol Jun 12, 2025
40c2ca9
Move `shared_helpers` test to a dedicated module
Kobzol Jun 12, 2025
2591571
Stop using Config for `tempdir-as-a-service` in `build_stamp` tests
Kobzol Jun 12, 2025
8540188
Remove `RefCell` from `cc/cxx/ar/ranlib`
Kobzol Jun 12, 2025
dbe15e3
Remove environment variable modification in `test_default_compiler_wasi`
Kobzol Jun 12, 2025
a71b463
Move submodule path cache from `parse_gitmodules` to `Builder`
Kobzol Jun 12, 2025
983fe4f
Simplify `configure_with_args`
Kobzol Jun 12, 2025
6feb9b7
Add lightweight snapshot testing for bootstrap tests
Kobzol Jun 12, 2025
96fd9fc
use `if let` guards where possible
fee1-dead Jun 15, 2025
1ac89f1
Refactor `rustc_attr_data_structures` documentation
xizheyin Jun 5, 2025
a0db28f
clarify `rustc_do_not_const_check` comment
fee1-dead Jun 15, 2025
3871203
Stabilize "file_lock" feature
cberner May 29, 2025
5ac1cd9
Test Debug for Location.
m-ou-se Jun 11, 2025
87456e1
Remove an `njn:` comment accidentaly left behind.
nnethercote Jun 16, 2025
ade2ad9
Add documentation on top of `rustc_middle/src/query/mod.rs`
xizheyin Jun 13, 2025
45bbb3d
Add documentation for `PathBuf`'s `FromIterator` and `Extend` impls
yotamofek Jun 9, 2025
94f7790
Add discriminant_for_variant to AdtDef
NotLebedev May 27, 2025
d4de032
Add discriminant_for_variant to CoroutineDef
NotLebedev May 27, 2025
7ce7fc5
Implement Stable for Discr
NotLebedev Mar 27, 2025
91a3630
Add test for `AdtDef::discriminant_for_variant`
NotLebedev Jun 4, 2025
4fc768e
Add test for `AdtDef::discriminant_for_variant` polymorphic over para…
NotLebedev Jun 4, 2025
9505b6e
Fix test description
NotLebedev Jun 6, 2025
743c2a4
Fix `-nopt` CI jobs
Kobzol Jun 16, 2025
3416087
Rollup merge of #141639 - NotLebedev:stable-mir-93, r=oli-obk
Kobzol Jun 16, 2025
3795658
Rollup merge of #142082 - xizheyin:rustc_attr_data_structures, r=jdon…
Kobzol Jun 16, 2025
c4e1174
Rollup merge of #142125 - cberner:file_lock_stable, r=ChrisDenton
Kobzol Jun 16, 2025
6092c1a
Rollup merge of #142236 - yotamofek:pr/std/pathbuf-extend-docs, r=tgr…
Kobzol Jun 16, 2025
d9c83bb
Rollup merge of #142373 - m-ou-se:debug-for-location, r=tgross35
Kobzol Jun 16, 2025
ac8a48d
Rollup merge of #142416 - Kobzol:bootstrap-cleanup-2, r=jieyouxu
Kobzol Jun 16, 2025
e036a56
Rollup merge of #142431 - Kobzol:bootstrap-snapshot-tests, r=jieyouxu
Kobzol Jun 16, 2025
2c4abc0
Rollup merge of #142450 - xizheyin:rustc-query-doc, r=SparrowLii
Kobzol Jun 16, 2025
dc16682
Rollup merge of #142528 - fee1-dead-contrib:push-rlxklunqkwmv, r=Ralf…
Kobzol Jun 16, 2025
1a56184
Rollup merge of #142530 - fee1-dead-contrib:push-klusvwusyqvq, r=comp…
Kobzol Jun 16, 2025
f1dd5fb
Rollup merge of #142561 - nnethercote:fix-njn-comment, r=chenyukang
Kobzol Jun 16, 2025
78d12b7
Rollup merge of #142566 - Kobzol:ci-nopt-fix, r=jieyouxu
Kobzol Jun 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 44 additions & 14 deletions compiler/rustc_attr_data_structures/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,24 +130,54 @@ impl Deprecation {
}
}

/// Represent parsed, *built in*, inert attributes.
/// Represents parsed *built-in* inert attributes.
///
/// That means attributes that are not actually ever expanded.
/// For more information on this, see the module docs on the [`rustc_attr_parsing`] crate.
/// They're instead used as markers, to guide the compilation process in various way in most every stage of the compiler.
/// These are kept around after the AST, into the HIR and further on.
/// ## Overview
/// These attributes are markers that guide the compilation process and are never expanded into other code.
/// They persist throughout the compilation phases, from AST to HIR and beyond.
///
/// The word "parsed" could be a little misleading here, because the parser already parses
/// attributes early on. However, the result, an [`ast::Attribute`]
/// is only parsed at a high level, still containing a token stream in many cases. That is
/// because the structure of the contents varies from attribute to attribute.
/// With a parsed attribute I mean that each attribute is processed individually into a
/// final structure, which on-site (the place where the attribute is useful for, think the
/// the place where `must_use` is checked) little to no extra parsing or validating needs to
/// happen.
/// ## Attribute Processing
/// While attributes are initially parsed by [`rustc_parse`] into [`ast::Attribute`], they still contain raw token streams
/// because different attributes have different internal structures. This enum represents the final,
/// fully parsed form of these attributes, where each variant contains contains all the information and
/// structure relevant for the specific attribute.
///
/// For more docs, look in [`rustc_attr_parsing`].
/// Some attributes can be applied multiple times to the same item, and they are "collapsed" into a single
/// semantic attribute. For example:
/// ```rust
/// #[repr(C)]
/// #[repr(packed)]
/// struct S { }
/// ```
/// This is equivalent to `#[repr(C, packed)]` and results in a single [`AttributeKind::Repr`] containing
/// both `C` and `packed` annotations. This collapsing happens during parsing and is reflected in the
/// data structures defined in this enum.
///
/// ## Usage
/// These parsed attributes are used throughout the compiler to:
/// - Control code generation (e.g., `#[repr]`)
/// - Mark API stability (`#[stable]`, `#[unstable]`)
/// - Provide documentation (`#[doc]`)
/// - Guide compiler behavior (e.g., `#[allow_internal_unstable]`)
///
/// ## Note on Attribute Organization
/// Some attributes like `InlineAttr`, `OptimizeAttr`, and `InstructionSetAttr` are defined separately
/// from this enum because they are used in specific compiler phases (like code generation) and don't
/// need to persist throughout the entire compilation process. They are typically processed and
/// converted into their final form earlier in the compilation pipeline.
///
/// For example:
/// - `InlineAttr` is used during code generation to control function inlining
/// - `OptimizeAttr` is used to control optimization levels
/// - `InstructionSetAttr` is used for target-specific code generation
///
/// These attributes are handled by their respective compiler passes in the [`rustc_codegen_ssa`] crate
/// and don't need to be preserved in the same way as the attributes in this enum.
///
/// For more details on attribute parsing, see the [`rustc_attr_parsing`] crate.
///
/// [`rustc_parse`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html
/// [`rustc_codegen_ssa`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/index.html
/// [`rustc_attr_parsing`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html
#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
pub enum AttributeKind {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_attr_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! Data structures for representing parsed attributes in the Rust compiler.
//! For detailed documentation about attribute processing,
//! see [rustc_attr_parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html).

// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(rust_logo)]
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_builtin_macros/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,7 @@ pub(crate) fn expand_test_or_bench(

let (item, is_stmt) = match item {
Annotatable::Item(i) => (i, false),
Annotatable::Stmt(stmt) if matches!(stmt.kind, ast::StmtKind::Item(_)) => {
// FIXME: Use an 'if let' guard once they are implemented
if let ast::StmtKind::Item(i) = stmt.kind { (i, true) } else { unreachable!() }
}
Annotatable::Stmt(box ast::Stmt { kind: ast::StmtKind::Item(i), .. }) => (i, true),
other => {
not_testable_error(cx, attr_sp, None);
return vec![other];
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use crate::base::ast::MetaItemInner;
use crate::errors;
use crate::expand::{self, AstFragment, Invocation};
use crate::module::DirOwnership;
use crate::stats::MacroStat;

// When adding new variants, make sure to
// adjust the `visit_*` / `flat_map_*` calls in `InvocationCollector`
Expand Down Expand Up @@ -1191,7 +1192,7 @@ pub struct ExtCtxt<'a> {
/// not to expand it again.
pub(super) expanded_inert_attrs: MarkedAttrs,
/// `-Zmacro-stats` data.
pub macro_stats: FxHashMap<(Symbol, MacroKind), crate::stats::MacroStat>, // njn: quals
pub macro_stats: FxHashMap<(Symbol, MacroKind), MacroStat>,
}

impl<'a> ExtCtxt<'a> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_legacy_const_generics, Normal, template!(List: "N"), ErrorFollowing,
EncodeCrossCrate::Yes,
),
// Do not const-check this function's body. It will always get replaced during CTFE.
// Do not const-check this function's body. It will always get replaced during CTFE via `hook_special_const_fn`.
rustc_attr!(
rustc_do_not_const_check, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::Yes, "`#[rustc_do_not_const_check]` skips const-check for this function's body",
Expand Down
64 changes: 60 additions & 4 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,64 @@
//! Defines the various compiler queries.
//!
//! For more information on the query system, see
//! ["Queries: demand-driven compilation"](https://rustc-dev-guide.rust-lang.org/query.html).
//! This chapter includes instructions for adding new queries.
//! # The rustc Query System: Query Definitions and Modifiers
//!
//! The core processes in rustc are shipped as queries. Each query is a demand-driven function from some key to a value.
//! The execution result of the function is cached and directly read during the next request, thereby improving compilation efficiency.
//! Some results are saved locally and directly read during the next compilation, which are core of incremental compilation.
//!
//! ## How to Read This Module
//!
//! Each `query` block in this file defines a single query, specifying its key and value types, along with various modifiers.
//! These query definitions are processed by the [`rustc_macros`], which expands them into the necessary boilerplate code
//! for the query system—including the [`Providers`] struct (a function table for all query implementations, where each field is
//! a function pointer to the actual provider), caching, and dependency graph integration.
//! **Note:** The `Providers` struct is not a Rust trait, but a struct generated by the `rustc_macros` to hold all provider functions.
//! The `rustc_macros` also supports a set of **query modifiers** (see below) that control the behavior of each query.
//!
//! The actual provider functions are implemented in various modules and registered into the `Providers` struct
//! during compiler initialization (see [`rustc_interface::passes::DEFAULT_QUERY_PROVIDERS`]).
//!
//! [`rustc_macros`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_macros/index.html
//! [`rustc_interface::passes::DEFAULT_QUERY_PROVIDERS`]: ../../rustc_interface/passes/static.DEFAULT_QUERY_PROVIDERS.html
//!
//! ## Query Modifiers
//!
//! Query modifiers are special flags that alter the behavior of a query. They are parsed and processed by the `rustc_macros`
//! The main modifiers are:
//!
//! - `desc { ... }`: Sets the human-readable description for diagnostics and profiling. Required for every query.
//! - `arena_cache`: Use an arena for in-memory caching of the query result.
//! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to true.
//! - `fatal_cycle`: If a dependency cycle is detected, abort compilation with a fatal error.
//! - `cycle_delay_bug`: If a dependency cycle is detected, emit a delayed bug instead of aborting immediately.
//! - `cycle_stash`: If a dependency cycle is detected, stash the error for later handling.
//! - `no_hash`: Do not hash the query result for incremental compilation; just mark as dirty if recomputed.
//! - `anon`: Make the query anonymous in the dependency graph (no dep node is created).
//! - `eval_always`: Always evaluate the query, ignoring its dependencies and cached results.
//! - `depth_limit`: Impose a recursion depth limit on the query to prevent stack overflows.
//! - `separate_provide_extern`: Use separate provider functions for local and external crates.
//! - `feedable`: Allow the query result to be set from another query ("fed" externally).
//! - `return_result_from_ensure_ok`: When called via `tcx.ensure_ok()`, return `Result<(), ErrorGuaranteed>` instead of `()`.
//! If the query needs to be executed and returns an error, the error is returned to the caller.
//! Only valid for queries returning `Result<_, ErrorGuaranteed>`.
//!
//! For the up-to-date list, see the `QueryModifiers` struct in
//! [`rustc_macros/src/query.rs`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_macros/src/query.rs)
//! and for more details in incremental compilation, see the
//! [Query modifiers in incremental compilation](https://rustc-dev-guide.rust-lang.org/queries/incremental-compilation-in-detail.html#query-modifiers) section of the rustc-dev-guide.
//!
//! ## Query Expansion and Code Generation
//!
//! The [`rustc_macros::rustc_queries`] macro expands each query definition into:
//! - A method on [`TyCtxt`] (and [`TyCtxtAt`]) for invoking the query.
//! - Provider traits and structs for supplying the query's value.
//! - Caching and dependency graph integration.
//! - Support for incremental compilation, disk caching, and arena allocation as controlled by the modifiers.
//!
//! [`rustc_macros::rustc_queries`]: ../../rustc_macros/macro.rustc_queries.html
//!
//! The macro-based approach allows the query system to be highly flexible and maintainable, while minimizing boilerplate.
//!
//! For more details, see the [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/query.html).

#![allow(unused_parens)]

Expand Down
27 changes: 11 additions & 16 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2273,23 +2273,18 @@ impl<'a> Parser<'a> {
),
// Also catches `fn foo(&a)`.
PatKind::Ref(ref inner_pat, mutab)
if matches!(inner_pat.clone().kind, PatKind::Ident(..)) =>
if let PatKind::Ident(_, ident, _) = inner_pat.clone().kind =>
{
match inner_pat.clone().kind {
PatKind::Ident(_, ident, _) => {
let mutab = mutab.prefix_str();
(
ident,
"self: ",
format!("{ident}: &{mutab}TypeName"),
"_: ",
pat.span.shrink_to_lo(),
pat.span,
pat.span.shrink_to_lo(),
)
}
_ => unreachable!(),
}
let mutab = mutab.prefix_str();
(
ident,
"self: ",
format!("{ident}: &{mutab}TypeName"),
"_: ",
pat.span.shrink_to_lo(),
pat.span,
pat.span.shrink_to_lo(),
)
}
_ => {
// Otherwise, try to get a type and emit a suggestion.
Expand Down
33 changes: 29 additions & 4 deletions compiler/rustc_smir/src/rustc_smir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ use rustc_middle::ty::layout::{
};
use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
use rustc_middle::ty::{
GenericPredicates, Instance, List, ScalarInt, TyCtxt, TypeVisitableExt, ValTree,
CoroutineArgsExt, GenericPredicates, Instance, List, ScalarInt, TyCtxt, TypeVisitableExt,
ValTree,
};
use rustc_middle::{mir, ty};
use rustc_span::def_id::LOCAL_CRATE;
Expand All @@ -22,9 +23,9 @@ use stable_mir::mir::mono::{InstanceDef, StaticDef};
use stable_mir::mir::{BinOp, Body, Place, UnOp};
use stable_mir::target::{MachineInfo, MachineSize};
use stable_mir::ty::{
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef,
ForeignItemKind, GenericArgs, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, Ty,
TyConst, TyKind, UintTy, VariantDef,
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, CoroutineDef, Discr, FieldDef, FnDef,
ForeignDef, ForeignItemKind, GenericArgs, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy,
Span, Ty, TyConst, TyKind, UintTy, VariantDef, VariantIdx,
};
use stable_mir::{Crate, CrateDef, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, Symbol};

Expand Down Expand Up @@ -447,6 +448,30 @@ impl<'tcx> SmirCtxt<'tcx> {
def.internal(&mut *tables, tcx).variants().len()
}

/// Discriminant for a given variant index of AdtDef
pub fn adt_discr_for_variant(&self, adt: AdtDef, variant: VariantIdx) -> Discr {
let mut tables = self.0.borrow_mut();
let tcx = tables.tcx;
let adt = adt.internal(&mut *tables, tcx);
let variant = variant.internal(&mut *tables, tcx);
adt.discriminant_for_variant(tcx, variant).stable(&mut *tables)
}

/// Discriminant for a given variand index and args of a coroutine
pub fn coroutine_discr_for_variant(
&self,
coroutine: CoroutineDef,
args: &GenericArgs,
variant: VariantIdx,
) -> Discr {
let mut tables = self.0.borrow_mut();
let tcx = tables.tcx;
let coroutine = coroutine.def_id().internal(&mut *tables, tcx);
let args = args.internal(&mut *tables, tcx);
let variant = variant.internal(&mut *tables, tcx);
args.as_coroutine().discriminant_for_variant(coroutine, tcx, variant).stable(&mut *tables)
}

/// The name of a variant.
pub fn variant_name(&self, def: VariantDef) -> Symbol {
let mut tables = self.0.borrow_mut();
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_smir/src/rustc_smir/convert/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -960,3 +960,11 @@ impl<'tcx> Stable<'tcx> for ty::ImplTraitInTraitData {
}
}
}

impl<'tcx> Stable<'tcx> for rustc_middle::ty::util::Discr<'tcx> {
type T = stable_mir::ty::Discr;

fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
stable_mir::ty::Discr { val: self.val, ty: self.ty.stable(tables) }
}
}
23 changes: 19 additions & 4 deletions compiler/rustc_smir/src/stable_mir/compiler_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ use stable_mir::mir::mono::{Instance, InstanceDef, StaticDef};
use stable_mir::mir::{BinOp, Body, Place, UnOp};
use stable_mir::target::MachineInfo;
use stable_mir::ty::{
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef,
ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics,
ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, TraitDecl,
TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef,
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, CoroutineDef, Discr, FieldDef, FnDef,
ForeignDef, ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates,
Generics, ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span,
TraitDecl, TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef, VariantIdx,
};
use stable_mir::{
AssocItems, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls,
Expand Down Expand Up @@ -230,6 +230,21 @@ impl<'tcx> SmirInterface<'tcx> {
self.cx.adt_variants_len(def)
}

/// Discriminant for a given variant index of AdtDef
pub(crate) fn adt_discr_for_variant(&self, adt: AdtDef, variant: VariantIdx) -> Discr {
self.cx.adt_discr_for_variant(adt, variant)
}

/// Discriminant for a given variand index and args of a coroutine
pub(crate) fn coroutine_discr_for_variant(
&self,
coroutine: CoroutineDef,
args: &GenericArgs,
variant: VariantIdx,
) -> Discr {
self.cx.coroutine_discr_for_variant(coroutine, args, variant)
}

/// The name of a variant.
pub(crate) fn variant_name(&self, def: VariantDef) -> Symbol {
self.cx.variant_name(def)
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_smir/src/stable_mir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,12 @@ crate_def! {
pub CoroutineDef;
}

impl CoroutineDef {
pub fn discriminant_for_variant(&self, args: &GenericArgs, idx: VariantIdx) -> Discr {
with(|cx| cx.coroutine_discr_for_variant(*self, args, idx))
}
}

crate_def! {
#[derive(Serialize)]
pub CoroutineClosureDef;
Expand Down Expand Up @@ -831,6 +837,15 @@ impl AdtDef {
pub fn repr(&self) -> ReprOptions {
with(|cx| cx.adt_repr(*self))
}

pub fn discriminant_for_variant(&self, idx: VariantIdx) -> Discr {
with(|cx| cx.adt_discr_for_variant(*self, idx))
}
}

pub struct Discr {
pub val: u128,
pub ty: Ty,
}

/// Definition of a variant, which can be either a struct / union field or an enum variant.
Expand Down
13 changes: 12 additions & 1 deletion library/core/src/panic/location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::fmt;
/// Files are compared as strings, not `Path`, which could be unexpected.
/// See [`Location::file`]'s documentation for more discussion.
#[lang = "panic_location"]
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[stable(feature = "panic_hooks", since = "1.10.0")]
pub struct Location<'a> {
// Note: this filename will have exactly one nul byte at its end, but otherwise
Expand All @@ -43,6 +43,17 @@ pub struct Location<'a> {
col: u32,
}

#[stable(feature = "panic_hooks", since = "1.10.0")]
impl fmt::Debug for Location<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Location")
.field("file", &self.file())
.field("line", &self.line)
.field("column", &self.col)
.finish()
}
}

impl<'a> Location<'a> {
/// Returns the source location of the caller of this function. If that function's caller is
/// annotated then its call location will be returned, and so on up the stack to the first call
Expand Down
8 changes: 8 additions & 0 deletions library/coretests/tests/panic/location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,11 @@ fn location_const_column() {
const COLUMN: u32 = CALLER.column();
assert_eq!(COLUMN, 40);
}

#[test]
fn location_debug() {
let f = format!("{:?}", Location::caller());
assert!(f.contains(&format!("{:?}", file!())));
assert!(f.contains("35"));
assert!(f.contains("29"));
}
Loading
Loading