Skip to content

Rollup of 11 pull requests #144058

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 29 commits into from
Jul 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
674724c
remove deprecated from core::ffi::c_str
hkBst Jul 2, 2025
2111525
Add test false-sealed-traits-note.rs
xizheyin Jul 4, 2025
4a261a1
Use relative visibility when noting sealed trait to reduce false posi…
xizheyin Jul 4, 2025
d44dcd4
update to literal-escaper-0.0.5
hkBst Jul 8, 2025
28af500
Opaque type collection: Guard against endlessly recursing free alias …
fmease Jul 11, 2025
500b743
tests: Test line debuginfo for linebreaked function parameters
Enselic Jul 13, 2025
5530744
Reword mismatched-lifetime-syntaxes text based on feedback
shepmaster Jul 10, 2025
e7f5bbe
remove description from rust toml struct
Shourya742 Jul 14, 2025
76967af
remove ccache from llvm
Shourya742 Jul 14, 2025
306928f
update change tracking with warning on removal of fields.
Shourya742 Jul 14, 2025
8e400f9
Fix ice for feature-gated cfg attributes applied to the crate
JonathanBrouwer Jul 15, 2025
bfa45ac
Add regression test
JonathanBrouwer Jul 15, 2025
42ec028
type_id_eq: check that the hash fully matches the type
RalfJung Jul 15, 2025
07a34c3
Make frame spans appear on a separate trace line
Stypox Jul 15, 2025
5d611e5
resolve: Move `self_binding` to `ModuleData`
petrochenkov Jul 6, 2025
8d71939
resolve: Use `module_map` and `get_module` less
petrochenkov Jul 6, 2025
8b8889d
resolve: Split `module_map` into two maps for local and extern modules
petrochenkov Jul 6, 2025
6849f81
resolve: Change `&mut Resolver` to `&Resolver` when possible
petrochenkov Jul 6, 2025
08fa971
Rollup merge of #143326 - hkBst:rm-deprecated-1, r=jhpratt
matthiaskrgr Jul 17, 2025
14b6ac4
Rollup merge of #143431 - xizheyin:143392, r=compiler-errors
matthiaskrgr Jul 17, 2025
52a405b
Rollup merge of #143550 - petrochenkov:lessmutres, r=lcnr
matthiaskrgr Jul 17, 2025
465ae94
Rollup merge of #143631 - hkBst:update-escaper-2, r=compiler-errors
matthiaskrgr Jul 17, 2025
f78cc42
Rollup merge of #143793 - fmease:lta-opaq-inf-recur, r=oli-obk
matthiaskrgr Jul 17, 2025
c8d2cbb
Rollup merge of #143880 - Enselic:fn-parameters-on-different-lines-de…
matthiaskrgr Jul 17, 2025
51f16b0
Rollup merge of #143914 - shepmaster:mismatched-lifetime-syntaxes-rew…
matthiaskrgr Jul 17, 2025
c97c38b
Rollup merge of #143926 - Shourya742:2025-07-14-remove-deprecated-fie…
matthiaskrgr Jul 17, 2025
4bf5787
Rollup merge of #143955 - Stypox:tracing-frame-filter, r=RalfJung
matthiaskrgr Jul 17, 2025
e7efa04
Rollup merge of #143975 - RalfJung:type-id-eq, r=oli-obk
matthiaskrgr Jul 17, 2025
5286836
Rollup merge of #143984 - JonathanBrouwer:fix-feature-gate-ice, r=Urgau
matthiaskrgr Jul 17, 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
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3136,9 +3136,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"

[[package]]
name = "rustc-literal-escaper"
version = "0.0.4"
version = "0.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab03008eb631b703dd16978282ae36c73282e7922fe101a4bd072a40ecea7b8b"
checksum = "e4ee29da77c5a54f42697493cd4c9b9f31b74df666a6c04dfc4fde77abe0438b"

[[package]]
name = "rustc-main"
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2024"
# tidy-alphabetical-start
bitflags = "2.4.1"
memchr = "2.7.4"
rustc-literal-escaper = "0.0.4"
rustc-literal-escaper = "0.0.5"
rustc_ast_ir = { path = "../rustc_ast_ir" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_index = { path = "../rustc_index" }
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_ast/src/util/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,11 @@ impl LitKind {
token::CStr => {
let s = symbol.as_str();
let mut buf = Vec::with_capacity(s.len());
unescape_c_str(s, |_span, c| match c {
unescape_c_str(s, |_span, res| match res {
Ok(MixedUnit::Char(c)) => {
buf.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes())
buf.extend_from_slice(c.get().encode_utf8(&mut [0; 4]).as_bytes())
}
Ok(MixedUnit::HighByte(b)) => buf.push(b),
Ok(MixedUnit::HighByte(b)) => buf.push(b.get()),
Err(err) => {
assert!(!err.is_fatal(), "failed to unescape C string literal")
}
Expand Down
53 changes: 30 additions & 23 deletions compiler/rustc_attr_parsing/src/attributes/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_session::parse::feature_err;
use rustc_span::{Span, Symbol, sym};
use thin_vec::ThinVec;

use crate::context::{AcceptContext, Stage};
use crate::context::{AcceptContext, ShouldEmit, Stage};
use crate::parser::{ArgParser, MetaItemListParser, MetaItemOrLitParser, NameValueParser};
use crate::{
CfgMatchesLintEmitter, fluent_generated, parse_version, session_diagnostics, try_gate_cfg,
Expand Down Expand Up @@ -90,7 +90,7 @@ fn parse_cfg_entry_version<S: Stage>(
list: &MetaItemListParser<'_>,
meta_span: Span,
) -> Option<CfgEntry> {
try_gate_cfg(sym::version, meta_span, cx.sess(), Some(cx.features()));
try_gate_cfg(sym::version, meta_span, cx.sess(), cx.features_option());
let Some(version) = list.single() else {
cx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { span: list.span });
return None;
Expand Down Expand Up @@ -119,7 +119,9 @@ fn parse_cfg_entry_target<S: Stage>(
list: &MetaItemListParser<'_>,
meta_span: Span,
) -> Option<CfgEntry> {
if !cx.features().cfg_target_compact() {
if let Some(features) = cx.features_option()
&& !features.cfg_target_compact()
{
feature_err(
cx.sess(),
sym::cfg_target_compact,
Expand Down Expand Up @@ -186,12 +188,13 @@ pub fn eval_config_entry(
cfg_entry: &CfgEntry,
id: NodeId,
features: Option<&Features>,
emit_lints: ShouldEmit,
) -> EvalConfigResult {
match cfg_entry {
CfgEntry::All(subs, ..) => {
let mut all = None;
for sub in subs {
let res = eval_config_entry(sess, sub, id, features);
let res = eval_config_entry(sess, sub, id, features, emit_lints);
// We cannot short-circuit because `eval_config_entry` emits some lints
if !res.as_bool() {
all.get_or_insert(res);
Expand All @@ -202,7 +205,7 @@ pub fn eval_config_entry(
CfgEntry::Any(subs, span) => {
let mut any = None;
for sub in subs {
let res = eval_config_entry(sess, sub, id, features);
let res = eval_config_entry(sess, sub, id, features, emit_lints);
// We cannot short-circuit because `eval_config_entry` emits some lints
if res.as_bool() {
any.get_or_insert(res);
Expand All @@ -214,7 +217,7 @@ pub fn eval_config_entry(
})
}
CfgEntry::Not(sub, span) => {
if eval_config_entry(sess, sub, id, features).as_bool() {
if eval_config_entry(sess, sub, id, features, emit_lints).as_bool() {
EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }
} else {
EvalConfigResult::True
Expand All @@ -228,24 +231,28 @@ pub fn eval_config_entry(
}
}
CfgEntry::NameValue { name, name_span, value, span } => {
match sess.psess.check_config.expecteds.get(name) {
Some(ExpectedValues::Some(values)) if !values.contains(&value.map(|(v, _)| v)) => {
id.emit_span_lint(
sess,
UNEXPECTED_CFGS,
*span,
BuiltinLintDiag::UnexpectedCfgValue((*name, *name_span), *value),
);
if let ShouldEmit::ErrorsAndLints = emit_lints {
match sess.psess.check_config.expecteds.get(name) {
Some(ExpectedValues::Some(values))
if !values.contains(&value.map(|(v, _)| v)) =>
{
id.emit_span_lint(
sess,
UNEXPECTED_CFGS,
*span,
BuiltinLintDiag::UnexpectedCfgValue((*name, *name_span), *value),
);
}
None if sess.psess.check_config.exhaustive_names => {
id.emit_span_lint(
sess,
UNEXPECTED_CFGS,
*span,
BuiltinLintDiag::UnexpectedCfgName((*name, *name_span), *value),
);
}
_ => { /* not unexpected */ }
}
None if sess.psess.check_config.exhaustive_names => {
id.emit_span_lint(
sess,
UNEXPECTED_CFGS,
*span,
BuiltinLintDiag::UnexpectedCfgName((*name, *name_span), *value),
);
}
_ => { /* not unexpected */ }
}

if sess.psess.config.contains(&(*name, value.map(|(v, _)| v))) {
Expand Down
27 changes: 23 additions & 4 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ impl Stage for Early {
sess: &'sess Session,
diag: impl for<'x> Diagnostic<'x>,
) -> ErrorGuaranteed {
if self.emit_errors {
if self.emit_errors.should_emit() {
sess.dcx().emit_err(diag)
} else {
sess.dcx().create_err(diag).delay_as_bug()
Expand Down Expand Up @@ -257,7 +257,7 @@ pub struct Early {
/// Whether to emit errors or delay them as a bug
/// For most attributes, the attribute will be parsed again in the `Late` stage and in this case the errors should be delayed
/// But for some, such as `cfg`, the attribute will be removed before the `Late` stage so errors must be emitted
pub emit_errors: bool,
pub emit_errors: ShouldEmit,
}
/// used when parsing attributes during ast lowering
pub struct Late;
Expand Down Expand Up @@ -558,6 +558,25 @@ pub enum OmitDoc {
Skip,
}

#[derive(Copy, Clone)]
pub enum ShouldEmit {
/// The operation will emit errors and lints.
/// This is usually what you need.
ErrorsAndLints,
/// The operation will emit *not* errors and lints.
/// Use this if you are *sure* that this operation will be called at a different time with `ShouldEmit::Emit`.
Nothing,
}

impl ShouldEmit {
pub fn should_emit(&self) -> bool {
match self {
ShouldEmit::ErrorsAndLints => true,
ShouldEmit::Nothing => false,
}
}
}

/// Context created once, for example as part of the ast lowering
/// context, through which all attributes can be lowered.
pub struct AttributeParser<'sess, S: Stage = Late> {
Expand Down Expand Up @@ -600,7 +619,7 @@ impl<'sess> AttributeParser<'sess, Early> {
tools: Vec::new(),
parse_only: Some(sym),
sess,
stage: Early { emit_errors: false },
stage: Early { emit_errors: ShouldEmit::Nothing },
};
let mut parsed = p.parse_attribute_list(
attrs,
Expand All @@ -623,7 +642,7 @@ impl<'sess> AttributeParser<'sess, Early> {
target_span: Span,
target_node_id: NodeId,
features: Option<&'sess Features>,
emit_errors: bool,
emit_errors: ShouldEmit,
parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &ArgParser<'_>) -> T,
template: &AttributeTemplate,
) -> T {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub use attributes::cfg_old::*;
pub use attributes::util::{
find_crate_name, is_builtin_attr, is_doc_alias_attrs_contain_symbol, parse_version,
};
pub use context::{AttributeParser, Early, Late, OmitDoc};
pub use context::{AttributeParser, Early, Late, OmitDoc, ShouldEmit};
pub use lints::emit_attribute_lint;

rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
99 changes: 54 additions & 45 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
use std::assert_matches::assert_matches;

use rustc_abi::{FieldIdx, Size};
use rustc_abi::{FieldIdx, HasDataLayout, Size};
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
use rustc_middle::mir::interpret::{read_target_uint, write_target_uint};
use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{Ty, TyCtxt};
Expand All @@ -30,7 +31,7 @@ pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAll
}
impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Generates a value of `TypeId` for `ty` in-place.
pub(crate) fn write_type_id(
fn write_type_id(
&mut self,
ty: Ty<'tcx>,
dest: &PlaceTy<'tcx, M::Provenance>,
Expand All @@ -48,8 +49,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// Here we rely on `TypeId` being a newtype around an array of pointers, so we
// first project to its only field and then the array elements.
let alloc_id = tcx.reserve_and_set_type_id_alloc(ty);
let first = self.project_field(dest, FieldIdx::ZERO)?;
let mut elem_iter = self.project_array_fields(&first)?;
let arr = self.project_field(dest, FieldIdx::ZERO)?;
let mut elem_iter = self.project_array_fields(&arr)?;
while let Some((_, elem)) = elem_iter.next(self)? {
// Decorate this part of the hash with provenance; leave the integer part unchanged.
let hash_fragment = self.read_scalar(&elem)?.to_target_usize(&tcx)?;
Expand All @@ -61,6 +62,52 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
interp_ok(())
}

/// Read a value of type `TypeId`, returning the type it represents.
pub(crate) fn read_type_id(
&self,
op: &OpTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, Ty<'tcx>> {
// `TypeId` is a newtype around an array of pointers. All pointers must have the same
// provenance, and that provenance represents the type.
let ptr_size = self.pointer_size().bytes_usize();
let arr = self.project_field(op, FieldIdx::ZERO)?;

let mut ty_and_hash = None;
let mut elem_iter = self.project_array_fields(&arr)?;
while let Some((idx, elem)) = elem_iter.next(self)? {
let elem = self.read_pointer(&elem)?;
let (elem_ty, elem_hash) = self.get_ptr_type_id(elem)?;
// If this is the first element, remember the type and its hash.
// If this is not the first element, ensure it is consistent with the previous ones.
let full_hash = match ty_and_hash {
None => {
let hash = self.tcx.type_id_hash(elem_ty).as_u128();
let mut hash_bytes = [0u8; 16];
write_target_uint(self.data_layout().endian, &mut hash_bytes, hash).unwrap();
ty_and_hash = Some((elem_ty, hash_bytes));
hash_bytes
}
Some((ty, hash_bytes)) => {
if ty != elem_ty {
throw_ub_format!(
"invalid `TypeId` value: not all bytes carry the same type id metadata"
);
}
hash_bytes
}
};
// Ensure the elem_hash matches the corresponding part of the full hash.
let hash_frag = &full_hash[(idx as usize) * ptr_size..][..ptr_size];
if read_target_uint(self.data_layout().endian, hash_frag).unwrap() != elem_hash.into() {
throw_ub_format!(
"invalid `TypeId` value: the hash does not match the type id metadata"
);
}
}

interp_ok(ty_and_hash.unwrap().0)
}

/// Returns `true` if emulation happened.
/// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own
/// intrinsic handling.
Expand Down Expand Up @@ -97,47 +144,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_type_id(tp_ty, dest)?;
}
sym::type_id_eq => {
// Both operands are `TypeId`, which is a newtype around an array of pointers.
// Project until we have the array elements.
let a_fields = self.project_field(&args[0], FieldIdx::ZERO)?;
let b_fields = self.project_field(&args[1], FieldIdx::ZERO)?;

let mut a_fields = self.project_array_fields(&a_fields)?;
let mut b_fields = self.project_array_fields(&b_fields)?;

let mut provenance_a = None;
let mut provenance_b = None;
let mut provenance_matches = true;

while let Some((i, a)) = a_fields.next(self)? {
let (_, b) = b_fields.next(self)?.unwrap();

let a = self.deref_pointer(&a)?;
let (a, offset_a) = self.get_ptr_type_id(a.ptr())?;

let b = self.deref_pointer(&b)?;
let (b, offset_b) = self.get_ptr_type_id(b.ptr())?;

if *provenance_a.get_or_insert(a) != a {
throw_ub_format!(
"type_id_eq: the first TypeId argument is invalid, the provenance of chunk {i} does not match the first chunk's"
)
}
if *provenance_b.get_or_insert(b) != b {
throw_ub_format!(
"type_id_eq: the second TypeId argument is invalid, the provenance of chunk {i} does not match the first chunk's"
)
}
provenance_matches &= a == b;

if offset_a != offset_b && provenance_matches {
throw_ub_format!(
"type_id_eq: one of the TypeId arguments is invalid, chunk {i} of the hash does not match the type it represents"
)
}
}

self.write_scalar(Scalar::from_bool(provenance_matches), dest)?;
let a_ty = self.read_type_id(&args[0])?;
let b_ty = self.read_type_id(&args[1])?;
self.write_scalar(Scalar::from_bool(a_ty == b_ty), dest)?;
}
sym::variant_count => {
let tp_ty = instance.args.type_at(0);
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -997,12 +997,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
pub fn get_ptr_type_id(
&self,
ptr: Pointer<Option<M::Provenance>>,
) -> InterpResult<'tcx, (Ty<'tcx>, Size)> {
) -> InterpResult<'tcx, (Ty<'tcx>, u64)> {
let (alloc_id, offset, _meta) = self.ptr_get_alloc_id(ptr, 0)?;
let GlobalAlloc::TypeId { ty } = self.tcx.global_alloc(alloc_id) else {
throw_ub_format!("type_id_eq: `TypeId` provenance is not a type id")
throw_ub_format!("invalid `TypeId` value: not all bytes carry type id metadata")
};
interp_ok((ty, offset))
interp_ok((ty, offset.bytes()))
}

pub fn get_ptr_fn(
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_const_eval/src/interpret/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{bug, mir};
use rustc_mir_dataflow::impls::always_storage_live_locals;
use rustc_span::Span;
use tracing::field::Empty;
use tracing::{info_span, instrument, trace};

use super::{
Expand Down Expand Up @@ -396,7 +397,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// Finish things up.
M::after_stack_push(self)?;
self.frame_mut().loc = Left(mir::Location::START);
let span = info_span!("frame", "{}", instance);
// `tracing_separate_thread` is used to instruct the chrome_tracing [tracing::Layer] in Miri
// to put the "frame" span on a separate trace thread/line than other spans, to make the
// visualization in https://ui.perfetto.dev easier to interpret. It is set to a value of
// [tracing::field::Empty] so that other tracing layers (e.g. the logger) will ignore it.
let span = info_span!("frame", tracing_separate_thread = Empty, "{}", instance);
self.frame_mut().tracing_span.enter(span);

interp_ok(())
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,7 @@ pub trait ResolverExpand {
fn next_node_id(&mut self) -> NodeId;
fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId;

fn resolve_dollar_crates(&mut self);
fn resolve_dollar_crates(&self);
fn visit_ast_fragment_with_placeholders(
&mut self,
expn_id: LocalExpnId,
Expand Down
Loading
Loading