Skip to content

Rollup of 6 pull requests #144637

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 16 commits into from
Jul 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
20 changes: 6 additions & 14 deletions compiler/rustc_attr_data_structures/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,10 @@ pub enum DeprecatedSince {
Err,
}

#[derive(
Copy,
Debug,
Eq,
PartialEq,
Encodable,
Decodable,
Clone,
HashStable_Generic,
PrintAttribute
)]
pub enum CoverageStatus {
/// Successfully-parsed value of a `#[coverage(..)]` attribute.
#[derive(Copy, Debug, Eq, PartialEq, Encodable, Decodable, Clone)]
#[derive(HashStable_Generic, PrintAttribute)]
pub enum CoverageAttrKind {
On,
Off,
}
Expand Down Expand Up @@ -304,8 +296,8 @@ pub enum AttributeKind {
/// Represents `#[const_trait]`.
ConstTrait(Span),

/// Represents `#[coverage]`.
Coverage(Span, CoverageStatus),
/// Represents `#[coverage(..)]`.
Coverage(Span, CoverageAttrKind),

///Represents `#[rustc_deny_explicit_impl]`.
DenyExplicitImpl(Span),
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rustc_attr_data_structures::{AttributeKind, CoverageStatus, OptimizeAttr, UsedBy};
use rustc_attr_data_structures::{AttributeKind, CoverageAttrKind, OptimizeAttr, UsedBy};
use rustc_feature::{AttributeTemplate, template};
use rustc_session::parse::feature_err;
use rustc_span::{Span, Symbol, sym};
Expand Down Expand Up @@ -78,16 +78,16 @@ impl<S: Stage> SingleAttributeParser<S> for CoverageParser {
return None;
};

let status = match arg.path().word_sym() {
Some(sym::off) => CoverageStatus::Off,
Some(sym::on) => CoverageStatus::On,
let kind = match arg.path().word_sym() {
Some(sym::off) => CoverageAttrKind::Off,
Some(sym::on) => CoverageAttrKind::On,
None | Some(_) => {
fail_incorrect_argument(arg.span());
return None;
}
};

Some(AttributeKind::Coverage(cx.attr_span, status))
Some(AttributeKind::Coverage(cx.attr_span, kind))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ pub fn inject(
ast::ItemKind::ExternCrate(None, Ident::new(name, ident_span)),
);

krate.items.insert(0, item);

let root = (edition == Edition2015).then_some(kw::PathRoot);

let import_path = root
Expand All @@ -75,6 +73,6 @@ pub fn inject(
}),
);

krate.items.insert(0, use_item);
krate.items.splice(0..0, [item, use_item]);
krate.items.len() - orig_num_items
}
48 changes: 25 additions & 23 deletions compiler/rustc_mir_transform/src/coverage/query.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rustc_attr_data_structures::{AttributeKind, CoverageStatus, find_attr};
use rustc_attr_data_structures::{AttributeKind, CoverageAttrKind, find_attr};
use rustc_index::bit_set::DenseBitSet;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::coverage::{BasicCoverageBlock, CoverageIdsInfo, CoverageKind, MappingKind};
Expand Down Expand Up @@ -32,16 +32,6 @@ fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
return false;
}

// Don't instrument functions with `#[automatically_derived]` on their
// enclosing impl block, on the assumption that most users won't care about
// coverage for derived impls.
if let Some(impl_of) = tcx.impl_of_assoc(def_id.to_def_id())
&& tcx.is_automatically_derived(impl_of)
{
trace!("InstrumentCoverage skipped for {def_id:?} (automatically derived)");
return false;
}

if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NAKED) {
trace!("InstrumentCoverage skipped for {def_id:?} (`#[naked]`)");
return false;
Expand All @@ -57,20 +47,32 @@ fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {

/// Query implementation for `coverage_attr_on`.
fn coverage_attr_on(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
// Check for annotations directly on this def.
if let Some(coverage_status) =
find_attr!(tcx.get_all_attrs(def_id), AttributeKind::Coverage(_, status) => status)
// Check for a `#[coverage(..)]` attribute on this def.
if let Some(kind) =
find_attr!(tcx.get_all_attrs(def_id), AttributeKind::Coverage(_sp, kind) => kind)
{
*coverage_status == CoverageStatus::On
} else {
match tcx.opt_local_parent(def_id) {
// Check the parent def (and so on recursively) until we find an
// enclosing attribute or reach the crate root.
Some(parent) => tcx.coverage_attr_on(parent),
// We reached the crate root without seeing a coverage attribute, so
// allow coverage instrumentation by default.
None => true,
match kind {
CoverageAttrKind::On => return true,
CoverageAttrKind::Off => return false,
}
};

// Treat `#[automatically_derived]` as an implied `#[coverage(off)]`, on
// the assumption that most users won't want coverage for derived impls.
//
// This affects not just the associated items of an impl block, but also
// any closures and other nested functions within those associated items.
if tcx.is_automatically_derived(def_id.to_def_id()) {
return false;
}

// Check the parent def (and so on recursively) until we find an
// enclosing attribute or reach the crate root.
match tcx.opt_local_parent(def_id) {
Some(parent) => tcx.coverage_attr_on(parent),
// We reached the crate root without seeing a coverage attribute, so
// allow coverage instrumentation by default.
None => true,
}
}

Expand Down
31 changes: 31 additions & 0 deletions compiler/rustc_mir_transform/src/instsimplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {

let terminator = block.terminator.as_mut().unwrap();
ctx.simplify_primitive_clone(terminator, &mut block.statements);
ctx.simplify_align_of_slice_val(terminator, &mut block.statements);
ctx.simplify_intrinsic_assert(terminator);
ctx.simplify_nounwind_call(terminator);
simplify_duplicate_switch_targets(terminator);
Expand Down Expand Up @@ -252,6 +253,36 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
terminator.kind = TerminatorKind::Goto { target: *destination_block };
}

// Convert `align_of_val::<[T]>(ptr)` to `align_of::<T>()`, since the
// alignment of a slice doesn't actually depend on metadata at all
// and the element type is always `Sized`.
//
// This is here so it can run after inlining, where it's more useful.
// (LowerIntrinsics is done in cleanup, before the optimization passes.)
fn simplify_align_of_slice_val(
&self,
terminator: &mut Terminator<'tcx>,
statements: &mut Vec<Statement<'tcx>>,
) {
if let TerminatorKind::Call {
func, args, destination, target: Some(destination_block), ..
} = &terminator.kind
&& args.len() == 1
&& let Some((fn_def_id, generics)) = func.const_fn_def()
&& self.tcx.is_intrinsic(fn_def_id, sym::align_of_val)
&& let ty::Slice(elem_ty) = *generics.type_at(0).kind()
{
statements.push(Statement::new(
terminator.source_info,
StatementKind::Assign(Box::new((
*destination,
Rvalue::NullaryOp(NullOp::AlignOf, elem_ty),
))),
));
terminator.kind = TerminatorKind::Goto { target: *destination_block };
}
}

fn simplify_nounwind_call(&self, terminator: &mut Terminator<'tcx>) {
let TerminatorKind::Call { ref func, ref mut unwind, .. } = terminator.kind else {
return;
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -785,9 +785,13 @@ impl<'a> Parser<'a> {
ExprKind::Call(_, _) => "a function call",
ExprKind::Await(_, _) => "`.await`",
ExprKind::Use(_, _) => "`.use`",
ExprKind::Yield(YieldKind::Postfix(_)) => "`.yield`",
ExprKind::Match(_, _, MatchKind::Postfix) => "a postfix match",
ExprKind::Err(_) => return Ok(with_postfix),
_ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
_ => unreachable!(
"did not expect {:?} as an illegal postfix operator following cast",
with_postfix.kind
),
}
);
let mut err = self.dcx().struct_span_err(span, msg);
Expand Down
129 changes: 54 additions & 75 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -910,22 +910,15 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc
span,
|this| {
this.visit_generic_params(&fn_ptr.generic_params, false);
this.with_lifetime_rib(
LifetimeRibKind::AnonymousCreateParameter {
binder: ty.id,
report_in_path: false,
},
|this| {
this.resolve_fn_signature(
ty.id,
false,
// We don't need to deal with patterns in parameters, because
// they are not possible for foreign or bodiless functions.
fn_ptr.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
&fn_ptr.decl.output,
)
},
);
this.resolve_fn_signature(
ty.id,
false,
// We don't need to deal with patterns in parameters, because
// they are not possible for foreign or bodiless functions.
fn_ptr.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
&fn_ptr.decl.output,
false,
)
},
)
}
Expand Down Expand Up @@ -1042,19 +1035,12 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc
self.visit_fn_header(&sig.header);
self.visit_ident(ident);
self.visit_generics(generics);
self.with_lifetime_rib(
LifetimeRibKind::AnonymousCreateParameter {
binder: fn_id,
report_in_path: false,
},
|this| {
this.resolve_fn_signature(
fn_id,
sig.decl.has_self(),
sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
&sig.decl.output,
);
},
self.resolve_fn_signature(
fn_id,
sig.decl.has_self(),
sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
&sig.decl.output,
false,
);
return;
}
Expand All @@ -1080,22 +1066,15 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc
.coroutine_kind
.map(|coroutine_kind| coroutine_kind.return_id());

this.with_lifetime_rib(
LifetimeRibKind::AnonymousCreateParameter {
binder: fn_id,
report_in_path: coro_node_id.is_some(),
},
|this| {
this.resolve_fn_signature(
fn_id,
declaration.has_self(),
declaration
.inputs
.iter()
.map(|Param { pat, ty, .. }| (Some(&**pat), &**ty)),
&declaration.output,
);
},
this.resolve_fn_signature(
fn_id,
declaration.has_self(),
declaration
.inputs
.iter()
.map(|Param { pat, ty, .. }| (Some(&**pat), &**ty)),
&declaration.output,
coro_node_id.is_some(),
);

if let Some(contract) = contract {
Expand Down Expand Up @@ -1307,19 +1286,12 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc
kind: LifetimeBinderKind::PolyTrait,
..
} => {
self.with_lifetime_rib(
LifetimeRibKind::AnonymousCreateParameter {
binder,
report_in_path: false,
},
|this| {
this.resolve_fn_signature(
binder,
false,
p_args.inputs.iter().map(|ty| (None, &**ty)),
&p_args.output,
)
},
self.resolve_fn_signature(
binder,
false,
p_args.inputs.iter().map(|ty| (None, &**ty)),
&p_args.output,
false,
);
break;
}
Expand Down Expand Up @@ -2236,25 +2208,32 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
has_self: bool,
inputs: impl Iterator<Item = (Option<&'ast Pat>, &'ast Ty)> + Clone,
output_ty: &'ast FnRetTy,
report_elided_lifetimes_in_path: bool,
) {
// Add each argument to the rib.
let elision_lifetime = self.resolve_fn_params(has_self, inputs);
debug!(?elision_lifetime);

let outer_failures = take(&mut self.diag_metadata.current_elision_failures);
let output_rib = if let Ok(res) = elision_lifetime.as_ref() {
self.r.lifetime_elision_allowed.insert(fn_id);
LifetimeRibKind::Elided(*res)
} else {
LifetimeRibKind::ElisionFailure
let rib = LifetimeRibKind::AnonymousCreateParameter {
binder: fn_id,
report_in_path: report_elided_lifetimes_in_path,
};
self.with_lifetime_rib(output_rib, |this| visit::walk_fn_ret_ty(this, output_ty));
let elision_failures =
replace(&mut self.diag_metadata.current_elision_failures, outer_failures);
if !elision_failures.is_empty() {
let Err(failure_info) = elision_lifetime else { bug!() };
self.report_missing_lifetime_specifiers(elision_failures, Some(failure_info));
}
self.with_lifetime_rib(rib, |this| {
// Add each argument to the rib.
let elision_lifetime = this.resolve_fn_params(has_self, inputs);
debug!(?elision_lifetime);

let outer_failures = take(&mut this.diag_metadata.current_elision_failures);
let output_rib = if let Ok(res) = elision_lifetime.as_ref() {
this.r.lifetime_elision_allowed.insert(fn_id);
LifetimeRibKind::Elided(*res)
} else {
LifetimeRibKind::ElisionFailure
};
this.with_lifetime_rib(output_rib, |this| visit::walk_fn_ret_ty(this, output_ty));
let elision_failures =
replace(&mut this.diag_metadata.current_elision_failures, outer_failures);
if !elision_failures.is_empty() {
let Err(failure_info) = elision_lifetime else { bug!() };
this.report_missing_lifetime_specifiers(elision_failures, Some(failure_info));
}
});
}

/// Resolve inside function parameters and parameter types.
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/mem/drop_guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::ops::{Deref, DerefMut};

/// Wrap a value and run a closure when dropped.
///
/// This is useful for quickly creating desructors inline.
/// This is useful for quickly creating destructors inline.
///
/// # Examples
///
Expand Down
Loading
Loading