Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
b7d6767
Normalize capture place `ty`s to prevent ICE
JohnTitor Feb 5, 2026
0d9f020
call `try_structurally_resolve_type` before emitting diag
JohnTitor Feb 11, 2026
1d395f1
Deeply normalize on next solver
JohnTitor Feb 12, 2026
a8c0441
improve normalization way
JohnTitor Feb 12, 2026
52cf4ba
Move normalization forward up
JohnTitor Feb 14, 2026
82b09a1
Normalize the whole `Place`
JohnTitor Feb 15, 2026
a4e7e0c
deeply normalize only on next solver
JohnTitor Feb 16, 2026
d79fe52
Remove comment about ExprUseVisitor
JohnTitor Feb 16, 2026
dddbf96
simplify `normalize_capture_place`
JohnTitor Feb 17, 2026
547c53a
add span_parent method in ProcMacroClientInterface
Shourya742 Feb 18, 2026
fc97d7e
update span_parent implementation to call span_parent in callback
Shourya742 Feb 18, 2026
93e0d9e
add span_parent in MockCallback
Shourya742 Feb 18, 2026
3efdde1
update ProcMacroClientHandle implementation
Shourya742 Feb 18, 2026
6cb5858
add SpanParentResult and SpanParent
Shourya742 Feb 18, 2026
2116aaa
add SpanParent implementation in bidirectional variant
Shourya742 Feb 18, 2026
b081bc8
rustc_abi: stabilize VariantIdx and FieldIdx
BennoLossin Feb 20, 2026
4eaf448
fix: Fix scrutinee expr indent for replace_if_let_with_match
A4-Tacks Feb 24, 2026
87e4a3d
fix: detect E0804 when casting raw ptr-to-dyn adds auto traits
Albab-Hasan Feb 24, 2026
81bcf97
internal: Skip rustfmt test if nightly toolchain is missing
Wilfred Feb 19, 2026
70bf845
Merge pull request #21681 from Wilfred/skip_test_on_nightly
lnicola Feb 24, 2026
54e9a6a
refactor 'valid for read/write' definition: exclude null
RalfJung Feb 14, 2026
ff62e9a
fix: no complete enum variant qualifier in pat
A4-Tacks Feb 24, 2026
d173db9
Don't panic on invalid notifications
lnicola Feb 25, 2026
6c2ec54
Merge pull request #21708 from lnicola/no-invalid-notification-panic
Veykril Feb 26, 2026
526c1af
Correctly handle `#[doc(alias = "...")]` attribute on inlined reexports
GuillaumeGomez Feb 26, 2026
4a2f9eb
Merge pull request #21699 from Albab-Hasan/fix/ptr-cast-add-auto-trai…
ShoyuVanilla Feb 27, 2026
f7e81f5
Merge pull request #21698 from A4-Tacks/indent-iflet-with-match
ShoyuVanilla Feb 27, 2026
17c945f
Merge pull request #21706 from A4-Tacks/redundant-enum-variant-pat
ShoyuVanilla Feb 27, 2026
148f0b1
Use -Zlockfile-path on every 1.95 nightly
lnicola Feb 27, 2026
1a365c5
Merge pull request #21716 from lnicola/lockfile-path-nightly
ShoyuVanilla Feb 27, 2026
171dae6
feat: migrate fix_visibility assist to SyntaxEditor
SpiZeak Feb 25, 2026
720020d
Merge pull request #21710 from SpiZeak/migrate-fix-visibility
ShoyuVanilla Feb 27, 2026
8f25f8c
fix comment about placeholders
jdonszelmann Feb 27, 2026
ea2a15f
and some typos
jdonszelmann Feb 27, 2026
2879033
fix: migrate to SyntaxEditor in generate_derive assist
SpiZeak Feb 27, 2026
6df2169
Fix LegacyKeyValueFormat report from docker build: aarch64-gnu-debug
homersimpsons Feb 25, 2026
54c505f
Fix ICE when macro-expanded extern crate shadows std
is57primenumber Feb 27, 2026
d52424c
Check usages of variables in subdiagnostics
JonathanBrouwer Feb 27, 2026
7b42859
add field representing types
BennoLossin Feb 20, 2026
350a964
Fix subdiagnostics that use non-local variables
JonathanBrouwer Feb 27, 2026
f6e527e
Improve code by ensuring that if new doc attributes are added, we wil…
GuillaumeGomez Feb 27, 2026
ab9e1da
Add regression test for `search_unbox` inlined reexport
GuillaumeGomez Feb 27, 2026
ca3867b
Remove redundant clone
AbstractiveNord Feb 27, 2026
c97f2c3
Apply tidy suggest
AbstractiveNord Feb 27, 2026
448f9d8
Merge pull request #21720 from SpiZeak/migrate-generate-derive
A4-Tacks Feb 28, 2026
97748ad
Improve cross-crate trait impl param mismatch suggestions
reddevilmidzy Nov 17, 2025
7a22108
Merge pull request #21669 from Shourya742/2026-02-18-add-span-parent
Veykril Feb 28, 2026
c9b2784
mark two polonius tests as known-bug
lqd Feb 28, 2026
54776ea
Rollup merge of #153211 - lnicola:sync-from-ra, r=lnicola
JonathanBrouwer Feb 28, 2026
4dd3fea
Rollup merge of #149027 - reddevilmidzy:suggest, r=madsmtm
JonathanBrouwer Feb 28, 2026
1acf1c5
Rollup merge of #152730 - BennoLossin:field-projections-lang-item, r=…
JonathanBrouwer Feb 28, 2026
c3f1dab
Rollup merge of #153136 - GuillaumeGomez:reexport-doc-alias, r=lolbin…
JonathanBrouwer Feb 28, 2026
0381e24
Rollup merge of #152165 - JohnTitor:issue-151579, r=lcnr
JonathanBrouwer Feb 28, 2026
94923f2
Rollup merge of #152615 - RalfJung:null-not-valid-for-read-write, r=M…
JonathanBrouwer Feb 28, 2026
185833e
Rollup merge of #153109 - homersimpsons:chore/fix-LegacyKeyValueForma…
JonathanBrouwer Feb 28, 2026
baa285c
Rollup merge of #153172 - jdonszelmann:placeholder-comment, r=lcnr
JonathanBrouwer Feb 28, 2026
d0a2fe8
Rollup merge of #153187 - is57primenumber:fix-ice-on-shadowing, r=pet…
JonathanBrouwer Feb 28, 2026
f3035e7
Rollup merge of #153190 - JonathanBrouwer:subdiag_variables, r=jdonsz…
JonathanBrouwer Feb 28, 2026
307e884
Rollup merge of #153200 - AbstractiveNord:lexer-less-clone, r=Kivooeo
JonathanBrouwer Feb 28, 2026
3ff038e
Rollup merge of #153216 - lqd:polonius-soundness-tests, r=Kivooeo
JonathanBrouwer Feb 28, 2026
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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4706,6 +4706,7 @@ dependencies = [
"ena",
"indexmap",
"rustc-hash 2.1.1",
"rustc_abi",
"rustc_ast_ir",
"rustc_data_structures",
"rustc_error_messages",
Expand Down
59 changes: 58 additions & 1 deletion compiler/rustc_abi/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,64 @@ mod simple;
mod ty;

#[cfg(feature = "nightly")]
pub use ty::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx};
pub use ty::{Layout, TyAbiInterface, TyAndLayout};

rustc_index::newtype_index! {
/// The *source-order* index of a field in a variant.
///
/// This is how most code after type checking refers to fields, rather than
/// using names (as names have hygiene complications and more complex lookup).
///
/// Particularly for `repr(Rust)` types, this may not be the same as *layout* order.
/// (It is for `repr(C)` `struct`s, however.)
///
/// For example, in the following types,
/// ```rust
/// # enum Never {}
/// # #[repr(u16)]
/// enum Demo1 {
/// Variant0 { a: Never, b: i32 } = 100,
/// Variant1 { c: u8, d: u64 } = 10,
/// }
/// struct Demo2 { e: u8, f: u16, g: u8 }
/// ```
/// `b` is `FieldIdx(1)` in `VariantIdx(0)`,
/// `d` is `FieldIdx(1)` in `VariantIdx(1)`, and
/// `f` is `FieldIdx(1)` in `VariantIdx(0)`.
#[cfg_attr(feature = "nightly", derive(rustc_macros::HashStable_Generic))]
#[encodable]
#[orderable]
#[gate_rustc_only]
pub struct FieldIdx {}
}

impl FieldIdx {
/// The second field, at index 1.
///
/// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs.
pub const ONE: FieldIdx = FieldIdx::from_u32(1);
}

rustc_index::newtype_index! {
/// The *source-order* index of a variant in a type.
///
/// For enums, these are always `0..variant_count`, regardless of any
/// custom discriminants that may have been defined, and including any
/// variants that may end up uninhabited due to field types. (Some of the
/// variants may not be present in a monomorphized ABI [`Variants`], but
/// those skipped variants are always counted when determining the *index*.)
///
/// `struct`s, `tuples`, and `unions`s are considered to have a single variant
/// with variant index zero, aka [`FIRST_VARIANT`].
#[cfg_attr(feature = "nightly", derive(rustc_macros::HashStable_Generic))]
#[encodable]
#[orderable]
#[gate_rustc_only]
pub struct VariantIdx {
/// Equivalent to `VariantIdx(0)`.
const FIRST_VARIANT = 0;
}
}

// A variant is absent if it's uninhabited and only has ZST fields.
// Present uninhabited variants only require space for their fields,
Expand Down
55 changes: 1 addition & 54 deletions compiler/rustc_abi/src/layout/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,14 @@ use std::ops::Deref;
use rustc_data_structures::intern::Interned;
use rustc_macros::HashStable_Generic;

use crate::layout::{FieldIdx, VariantIdx};
use crate::{
AbiAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche,
PointeeInfo, Primitive, Size, Variants,
};

// Explicitly import `Float` to avoid ambiguity with `Primitive::Float`.

rustc_index::newtype_index! {
/// The *source-order* index of a field in a variant.
///
/// This is how most code after type checking refers to fields, rather than
/// using names (as names have hygiene complications and more complex lookup).
///
/// Particularly for `repr(Rust)` types, this may not be the same as *layout* order.
/// (It is for `repr(C)` `struct`s, however.)
///
/// For example, in the following types,
/// ```rust
/// # enum Never {}
/// # #[repr(u16)]
/// enum Demo1 {
/// Variant0 { a: Never, b: i32 } = 100,
/// Variant1 { c: u8, d: u64 } = 10,
/// }
/// struct Demo2 { e: u8, f: u16, g: u8 }
/// ```
/// `b` is `FieldIdx(1)` in `VariantIdx(0)`,
/// `d` is `FieldIdx(1)` in `VariantIdx(1)`, and
/// `f` is `FieldIdx(1)` in `VariantIdx(0)`.
#[derive(HashStable_Generic)]
#[encodable]
#[orderable]
pub struct FieldIdx {}
}

impl FieldIdx {
/// The second field, at index 1.
///
/// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs.
pub const ONE: FieldIdx = FieldIdx::from_u32(1);
}

rustc_index::newtype_index! {
/// The *source-order* index of a variant in a type.
///
/// For enums, these are always `0..variant_count`, regardless of any
/// custom discriminants that may have been defined, and including any
/// variants that may end up uninhabited due to field types. (Some of the
/// variants may not be present in a monomorphized ABI [`Variants`], but
/// those skipped variants are always counted when determining the *index*.)
///
/// `struct`s, `tuples`, and `unions`s are considered to have a single variant
/// with variant index zero, aka [`FIRST_VARIANT`].
#[derive(HashStable_Generic)]
#[encodable]
#[orderable]
pub struct VariantIdx {
/// Equivalent to `VariantIdx(0)`.
const FIRST_VARIANT = 0;
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
#[rustc_pass_by_value]
pub struct Layout<'a>(pub Interned<'a, LayoutData<FieldIdx, VariantIdx>>);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ pub use canon_abi::{ArmCall, CanonAbi, InterruptKind, X86Call};
#[cfg(feature = "nightly")]
pub use extern_abi::CVariadicStatus;
pub use extern_abi::{ExternAbi, all_names};
pub use layout::{FIRST_VARIANT, FieldIdx, LayoutCalculator, LayoutCalculatorError, VariantIdx};
#[cfg(feature = "nightly")]
pub use layout::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx};
pub use layout::{LayoutCalculator, LayoutCalculatorError};
pub use layout::{Layout, TyAbiInterface, TyAndLayout};

/// Requirements for a `StableHashingContext` to be used in this crate.
/// This is a hack to allow using the `HashStable_Generic` derive macro
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2553,6 +2553,11 @@ pub enum TyKind {
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
/// just as part of the type system.
Pat(Box<Ty>, Box<TyPat>),
/// A `field_of` expression (e.g., `builtin # field_of(Struct, field)`).
///
/// Usually not written directly in user code but indirectly via the macro
/// `core::field::field_of!(...)`.
FieldOf(Box<Ty>, Option<Ident>, Ident),
/// Sometimes we need a dummy value when no error has occurred.
Dummy,
/// Placeholder for a kind that has failed to be defined.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/util/classify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
| ast::TyKind::ImplicitSelf
| ast::TyKind::CVarArgs
| ast::TyKind::Pat(..)
| ast::TyKind::FieldOf(..)
| ast::TyKind::Dummy
| ast::TyKind::Err(..) => break None,
}
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
TyKind::Pat(ty, pat) => {
hir::TyKind::Pat(self.lower_ty_alloc(ty, itctx), self.lower_ty_pat(pat, ty.span))
}
TyKind::FieldOf(ty, variant, field) => hir::TyKind::FieldOf(
self.lower_ty_alloc(ty, itctx),
self.arena.alloc(hir::TyFieldPath {
variant: variant.map(|variant| self.lower_ident(variant)),
field: self.lower_ident(*field),
}),
),
TyKind::MacCall(_) => {
span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
}
Expand Down
17 changes: 17 additions & 0 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,23 @@ impl<'a> State<'a> {
self.word(" is ");
self.print_ty_pat(pat);
}
ast::TyKind::FieldOf(ty, variant, field) => {
self.word("builtin # field_of");
self.popen();
let ib = self.ibox(0);
self.print_type(ty);
self.word(",");
self.space();

if let Some(variant) = variant {
self.print_ident(*variant);
self.word(".");
}
self.print_ident(*field);

self.end(ib);
self.pclose();
}
}
self.end(ib);
}
Expand Down
30 changes: 26 additions & 4 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use rustc_middle::mir::AssertMessage;
use rustc_middle::mir::interpret::ReportedErrorInfo;
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout, ValidityRequirement};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{bug, mir};
use rustc_middle::ty::{self, FieldInfo, Ty, TyCtxt};
use rustc_middle::{bug, mir, span_bug};
use rustc_span::{Span, Symbol, sym};
use rustc_target::callconv::FnAbi;
use tracing::debug;
Expand All @@ -23,8 +23,9 @@ use crate::errors::{LongRunning, LongRunningWarn};
use crate::interpret::{
self, AllocId, AllocInit, AllocRange, ConstAllocation, CtfeProvenance, FnArg, Frame,
GlobalAlloc, ImmTy, InterpCx, InterpResult, OpTy, PlaceTy, Pointer, RangeSet, Scalar,
compile_time_machine, err_inval, interp_ok, throw_exhaust, throw_inval, throw_ub,
throw_ub_custom, throw_unsup, throw_unsup_format, type_implements_dyn_trait,
compile_time_machine, ensure_monomorphic_enough, err_inval, interp_ok, throw_exhaust,
throw_inval, throw_ub, throw_ub_custom, throw_unsup, throw_unsup_format,
type_implements_dyn_trait,
};

/// When hitting this many interpreted terminators we emit a deny by default lint
Expand Down Expand Up @@ -619,6 +620,27 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
ecx.write_type_info(ty, dest)?;
}

sym::field_offset => {
let frt_ty = instance.args.type_at(0);
ensure_monomorphic_enough(ecx.tcx.tcx, frt_ty)?;

let (ty, variant, field) = if let ty::Adt(def, args) = frt_ty.kind()
&& let Some(FieldInfo { base, variant_idx, field_idx, .. }) =
def.field_representing_type_info(ecx.tcx.tcx, args)
{
(base, variant_idx, field_idx)
} else {
span_bug!(ecx.cur_span(), "expected field representing type, got {frt_ty}")
};
let layout = ecx.layout_of(ty)?;
let cx = ty::layout::LayoutCx::new(ecx.tcx.tcx, ecx.typing_env());

let layout = layout.for_variant(&cx, variant);
let offset = layout.fields.offset(field.index()).bytes();

ecx.write_scalar(Scalar::from_target_usize(offset, ecx), dest)?;
}

_ => {
// We haven't handled the intrinsic, let's see if we can use a fallback body.
if ecx.tcx.intrinsic(instance.def_id()).unwrap().must_be_overridden {
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_const_eval/src/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ use self::place::{MemPlace, Place};
pub use self::projection::{OffsetMode, Projectable};
pub use self::stack::{Frame, FrameInfo, LocalState, ReturnContinuation};
pub use self::util::EnteredTraceSpan;
pub(crate) use self::util::{create_static_alloc, type_implements_dyn_trait};
pub(crate) use self::util::{
create_static_alloc, ensure_monomorphic_enough, type_implements_dyn_trait,
};
pub use self::validity::{CtfeValidationMode, RangeSet, RefTracking};
pub use self::visitor::ValueVisitor;
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ declare_features! (
(internal, custom_mir, "1.65.0", None),
/// Implementation details of externally implementable items
(internal, eii_internals, "1.94.0", None),
/// Implementation details of field representing types.
(internal, field_representing_type_raw, "CURRENT_RUSTC_VERSION", None),
/// Outputs useful `assert!` messages
(unstable, generic_assert, "1.63.0", None),
/// Allows using the #[rustc_intrinsic] attribute.
Expand Down Expand Up @@ -486,6 +488,8 @@ declare_features! (
(unstable, ffi_const, "1.45.0", Some(58328)),
/// Allows the use of `#[ffi_pure]` on foreign functions.
(unstable, ffi_pure, "1.45.0", Some(58329)),
/// Experimental field projections.
(incomplete, field_projections, "CURRENT_RUSTC_VERSION", Some(145383)),
/// Allows marking trait functions as `final` to prevent overriding impls
(unstable, final_associated_functions, "CURRENT_RUSTC_VERSION", Some(131179)),
/// Controlling the behavior of fmt::Debug
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1741,6 +1741,12 @@ impl<'hir> Block<'hir> {
}
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct TyFieldPath {
pub variant: Option<Ident>,
pub field: Ident,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct TyPat<'hir> {
#[stable_hasher(ignore)]
Expand Down Expand Up @@ -3804,6 +3810,10 @@ pub enum TyKind<'hir, Unambig = ()> {
Err(rustc_span::ErrorGuaranteed),
/// Pattern types (`pattern_type!(u32 is 1..)`)
Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
/// Field representing type (`field_of!(Struct, field)`).
///
/// The optional ident is the variant when an enum is passed `field_of!(Enum, Variant.field)`.
FieldOf(&'hir Ty<'hir>, &'hir TyFieldPath),
/// `TyKind::Infer` means the type should be inferred instead of it having been
/// specified. This can appear anywhere in a type.
///
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,11 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v, AmbigArg>) -
try_visit!(visitor.visit_ty_unambig(ty));
try_visit!(visitor.visit_pattern_type_pattern(pat));
}
TyKind::FieldOf(ty, TyFieldPath { variant, field }) => {
try_visit!(visitor.visit_ty_unambig(ty));
visit_opt!(visitor, visit_ident, *variant);
try_visit!(visitor.visit_ident(*field));
}
}
V::Result::output()
}
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,13 @@ language_item_table! {
// Reborrowing related lang-items
Reborrow, sym::reborrow, reborrow, Target::Trait, GenericRequirement::Exact(0);
CoerceShared, sym::coerce_shared, coerce_shared, Target::Trait, GenericRequirement::Exact(0);

// Field representing types.
FieldRepresentingType, sym::field_representing_type, field_representing_type, Target::Struct, GenericRequirement::Exact(3);
Field, sym::field, field, Target::Trait, GenericRequirement::Exact(0);
FieldBase, sym::field_base, field_base, Target::AssocTy, GenericRequirement::Exact(0);
FieldType, sym::field_type, field_type, Target::AssocTy, GenericRequirement::Exact(0);
FieldOffset, sym::field_offset, field_offset, Target::AssocConst, GenericRequirement::Exact(0);
}

/// The requirement imposed on the generics of a lang item
Expand Down
Loading
Loading