Skip to content

Rollup of 7 pull requests #145236

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 31 commits into from
Aug 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
30033b4
document assumptions about `Clone` and `Eq` traits
gewitternacht Jul 22, 2025
cdbcd72
remove trailing whitespace
gewitternacht Jul 22, 2025
623317e
add links to collections
gewitternacht Jul 22, 2025
c72bb70
clearer wording for `unsafe` code
gewitternacht Jul 29, 2025
6e75abd
std: sys: io: io_slice: Add UEFI types
Ayush1325 Jul 20, 2025
b4675dc
add download_ci_rustc_commit function and invoke from parse_inner
Shourya742 Aug 8, 2025
111a0e8
add parse_download_ci_llvm function and invoke from parse_inner
Shourya742 Aug 8, 2025
7eb8f60
add is_system_llvm function and invoke from parse_inner
Shourya742 Aug 9, 2025
134fcc8
add git_info function and invoke from parse_inner
Shourya742 Aug 9, 2025
2213b7a
add ci_llvm_root function and invoke from parse_inner
Shourya742 Aug 9, 2025
621af4a
add read_file_by_commit function and invoke from parse_inner
Shourya742 Aug 9, 2025
aad54a8
invoke functions from methods
Shourya742 Aug 9, 2025
8612db2
extend download context and change functions to directly use that
Shourya742 Aug 9, 2025
bfa6b56
add review comments
Shourya742 Aug 9, 2025
f604dd1
Let forward_ref_* macros accept multiple attributes, and require attr…
clarfonthey Jul 14, 2025
bb32e31
Constify remaining operators
clarfonthey Jul 15, 2025
1aa5668
Point at the `Fn()` or `FnMut()` bound that coerced a closure, which …
estebank Jul 28, 2025
2484e18
Add support for method calls
estebank Aug 7, 2025
74496bc
review comments
estebank Aug 10, 2025
e9609ab
Account for macros when trying to point at inference cause
estebank Aug 10, 2025
d9bd24d
Add test showing innecessary inference span
estebank Aug 10, 2025
48816e7
Do not point at macro invocation when providing inference context
estebank Aug 10, 2025
74c3727
Remove unnecessary parentheses in `assert!`s
estebank Aug 10, 2025
fadc961
mention `Hash` and `Ord`; refine description of `derive`
gewitternacht Aug 10, 2025
d06b3b4
Rollup merge of #143949 - clarfonthey:const-arith-ops, r=Amanieu
Zalathar Aug 11, 2025
2c314f9
Rollup merge of #144330 - gewitternacht:document-clone-eq, r=Amanieu
Zalathar Aug 11, 2025
3724e13
Rollup merge of #144350 - Ayush1325:uefi-io, r=tgross35,nicholasbishop
Zalathar Aug 11, 2025
907076c
Rollup merge of #144558 - estebank:issue-68119, r=lcnr
Zalathar Aug 11, 2025
2f1d61a
Rollup merge of #145149 - Shourya742:2025-07-08-convert-config-method…
Zalathar Aug 11, 2025
44c9ece
Rollup merge of #145227 - estebank:tweak-inference-span, r=joshtriplett
Zalathar Aug 11, 2025
fd7d724
Rollup merge of #145228 - estebank:unnecessary-parens, r=joshtriplett
Zalathar Aug 11, 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
50 changes: 49 additions & 1 deletion compiler/rustc_borrowck/src/diagnostics/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use rustc_middle::bug;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex};
use rustc_span::{BytePos, ExpnKind, MacroKind, Span};
use rustc_span::def_id::DefId;
use rustc_span::{BytePos, DUMMY_SP, ExpnKind, MacroKind, Span};
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
use rustc_trait_selection::infer::InferCtxtExt;
use tracing::debug;
Expand Down Expand Up @@ -507,12 +508,18 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
);

let closure_span = tcx.def_span(def_id);

self.cannot_move_out_of(span, &place_description)
.with_span_label(upvar_span, "captured outer variable")
.with_span_label(
closure_span,
format!("captured by this `{closure_kind}` closure"),
)
.with_span_help(
self.get_closure_bound_clause_span(*def_id),
"`Fn` and `FnMut` closures require captured values to be able to be \
consumed multiple times, but an `FnOnce` consume them only once",
)
}
_ => {
let source = self.borrowed_content_source(deref_base);
Expand Down Expand Up @@ -561,6 +568,47 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
err
}

fn get_closure_bound_clause_span(&self, def_id: DefId) -> Span {
let tcx = self.infcx.tcx;
let typeck_result = tcx.typeck(self.mir_def_id());
// Check whether the closure is an argument to a call, if so,
// get the instantiated where-bounds of that call.
let closure_hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
let hir::Node::Expr(parent) = tcx.parent_hir_node(closure_hir_id) else { return DUMMY_SP };

let predicates = match parent.kind {
hir::ExprKind::Call(callee, _) => {
let Some(ty) = typeck_result.node_type_opt(callee.hir_id) else { return DUMMY_SP };
let ty::FnDef(fn_def_id, args) = ty.kind() else { return DUMMY_SP };
tcx.predicates_of(fn_def_id).instantiate(tcx, args)
}
hir::ExprKind::MethodCall(..) => {
let Some((_, method)) = typeck_result.type_dependent_def(parent.hir_id) else {
return DUMMY_SP;
};
let args = typeck_result.node_args(parent.hir_id);
tcx.predicates_of(method).instantiate(tcx, args)
}
_ => return DUMMY_SP,
};

// Check whether one of the where-bounds requires the closure to impl `Fn[Mut]`.
for (pred, span) in predicates.predicates.iter().zip(predicates.spans.iter()) {
if let Some(clause) = pred.as_trait_clause()
&& let ty::Closure(clause_closure_def_id, _) = clause.self_ty().skip_binder().kind()
&& *clause_closure_def_id == def_id
&& (tcx.lang_items().fn_mut_trait() == Some(clause.def_id())
|| tcx.lang_items().fn_trait() == Some(clause.def_id()))
{
// Found `<TyOfCapturingClosure as FnMut>`
// We point at the `Fn()` or `FnMut()` bound that coerced the closure, which
// could be changed to `FnOnce()` to avoid the move error.
return *span;
}
}
DUMMY_SP
}

fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diag<'_>, span: Span) {
match error {
GroupedMoveError::MovesFromPlace { mut binds_to, move_from, .. } => {
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -847,17 +847,18 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
self
}

with_fn! { with_span_help,
/// Prints the span with some help above it.
/// This is like [`Diag::help()`], but it gets its own span.
#[rustc_lint_diagnostics]
pub fn span_help<S: Into<MultiSpan>>(
pub fn span_help(
&mut self,
sp: S,
sp: impl Into<MultiSpan>,
msg: impl Into<SubdiagMessage>,
) -> &mut Self {
self.sub(Level::Help, msg, sp.into());
self
}
} }

/// Disallow attaching suggestions to this diagnostic.
/// Any suggestions attached e.g. with the `span_suggestion_*` methods
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) {
match (self.tcx.parent_hir_node(expr.hir_id), error) {
(hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), init: Some(init), .. }), _)
if init.hir_id == expr.hir_id =>
if init.hir_id == expr.hir_id && !ty.span.source_equal(init.span) =>
{
// Point at `let` assignment type.
err.span_label(ty.span, "expected due to this");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
span,
format!("this is an iterator with items of type `{}`", args.type_at(0)),
);
} else {
} else if !span.overlaps(cause.span) {
let expected_ty = self.tcx.short_string(expected_ty, err.long_ty_path());
err.span_label(span, format!("this expression has type `{expected_ty}`"));
}
Expand Down
33 changes: 33 additions & 0 deletions library/core/src/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,34 @@ mod uninit;
/// // Note: With the manual implementations the above line will compile.
/// ```
///
/// ## `Clone` and `PartialEq`/`Eq`
/// `Clone` is intended for the duplication of objects. Consequently, when implementing
/// both `Clone` and [`PartialEq`], the following property is expected to hold:
/// ```text
/// x == x -> x.clone() == x
/// ```
/// In other words, if an object compares equal to itself,
/// its clone must also compare equal to the original.
///
/// For types that also implement [`Eq`] – for which `x == x` always holds –
/// this implies that `x.clone() == x` must always be true.
/// Standard library collections such as
/// [`HashMap`], [`HashSet`], [`BTreeMap`], [`BTreeSet`] and [`BinaryHeap`]
/// rely on their keys respecting this property for correct behavior.
/// Furthermore, these collections require that cloning a key preserves the outcome of the
/// [`Hash`] and [`Ord`] methods. Thankfully, this follows automatically from `x.clone() == x`
/// if `Hash` and `Ord` are correctly implemented according to their own requirements.
///
/// When deriving both `Clone` and [`PartialEq`] using `#[derive(Clone, PartialEq)]`
/// or when additionally deriving [`Eq`] using `#[derive(Clone, PartialEq, Eq)]`,
/// then this property is automatically upheld – provided that it is satisfied by
/// the underlying types.
///
/// Violating this property is a logic error. The behavior resulting from a logic error is not
/// specified, but users of the trait must ensure that such logic errors do *not* result in
/// undefined behavior. This means that `unsafe` code **must not** rely on this property
/// being satisfied.
///
/// ## Additional implementors
///
/// In addition to the [implementors listed below][impls],
Expand All @@ -152,6 +180,11 @@ mod uninit;
/// (even if the referent doesn't),
/// while variables captured by mutable reference never implement `Clone`.
///
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
/// [`HashSet`]: ../../std/collections/struct.HashSet.html
/// [`BTreeMap`]: ../../std/collections/struct.BTreeMap.html
/// [`BTreeSet`]: ../../std/collections/struct.BTreeSet.html
/// [`BinaryHeap`]: ../../std/collections/struct.BinaryHeap.html
/// [impls]: #implementors
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "clone"]
Expand Down
38 changes: 13 additions & 25 deletions library/core/src/internal_macros.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
// implements the unary operator "op &T"
// based on "op T" where T is expected to be `Copy`able
macro_rules! forward_ref_unop {
(impl $imp:ident, $method:ident for $t:ty) => {
forward_ref_unop!(impl $imp, $method for $t,
#[stable(feature = "rust1", since = "1.0.0")]);
};
(impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => {
#[$attr]
impl $imp for &$t {
(impl $imp:ident, $method:ident for $t:ty, $(#[$attr:meta])+) => {
$(#[$attr])+
impl const $imp for &$t {
type Output = <$t as $imp>::Output;

#[inline]
Expand All @@ -21,13 +17,9 @@ macro_rules! forward_ref_unop {
// implements binary operators "&T op U", "T op &U", "&T op &U"
// based on "T op U" where T and U are expected to be `Copy`able
macro_rules! forward_ref_binop {
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
forward_ref_binop!(impl $imp, $method for $t, $u,
#[stable(feature = "rust1", since = "1.0.0")]);
};
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
impl<'a> $imp<$u> for &'a $t {
(impl $imp:ident, $method:ident for $t:ty, $u:ty, $(#[$attr:meta])+) => {
$(#[$attr])+
impl const $imp<$u> for &$t {
type Output = <$t as $imp<$u>>::Output;

#[inline]
Expand All @@ -37,8 +29,8 @@ macro_rules! forward_ref_binop {
}
}

#[$attr]
impl $imp<&$u> for $t {
$(#[$attr])+
impl const $imp<&$u> for $t {
type Output = <$t as $imp<$u>>::Output;

#[inline]
Expand All @@ -48,8 +40,8 @@ macro_rules! forward_ref_binop {
}
}

#[$attr]
impl $imp<&$u> for &$t {
$(#[$attr])+
impl const $imp<&$u> for &$t {
type Output = <$t as $imp<$u>>::Output;

#[inline]
Expand All @@ -64,13 +56,9 @@ macro_rules! forward_ref_binop {
// implements "T op= &U", based on "T op= U"
// where U is expected to be `Copy`able
macro_rules! forward_ref_op_assign {
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
forward_ref_op_assign!(impl $imp, $method for $t, $u,
#[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]);
};
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
impl $imp<&$u> for $t {
(impl $imp:ident, $method:ident for $t:ty, $u:ty, $(#[$attr:meta])+) => {
$(#[$attr])+
impl const $imp<&$u> for $t {
#[inline]
#[track_caller]
fn $method(&mut self, other: &$u) {
Expand Down
47 changes: 30 additions & 17 deletions library/core/src/net/ip_addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use super::display_buffer::DisplayBuffer;
use crate::cmp::Ordering;
use crate::fmt::{self, Write};
use crate::hash::{Hash, Hasher};
use crate::iter;
use crate::mem::transmute;
use crate::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not};

Expand Down Expand Up @@ -2348,20 +2347,24 @@ impl const From<[u16; 8]> for IpAddr {
}

#[stable(feature = "ip_bitops", since = "1.75.0")]
impl Not for Ipv4Addr {
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl const Not for Ipv4Addr {
type Output = Ipv4Addr;

#[inline]
fn not(mut self) -> Ipv4Addr {
for octet in &mut self.octets {
*octet = !*octet;
let mut idx = 0;
while idx < 4 {
self.octets[idx] = !self.octets[idx];
idx += 1;
}
self
}
}

#[stable(feature = "ip_bitops", since = "1.75.0")]
impl Not for &'_ Ipv4Addr {
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl const Not for &'_ Ipv4Addr {
type Output = Ipv4Addr;

#[inline]
Expand All @@ -2371,20 +2374,24 @@ impl Not for &'_ Ipv4Addr {
}

#[stable(feature = "ip_bitops", since = "1.75.0")]
impl Not for Ipv6Addr {
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl const Not for Ipv6Addr {
type Output = Ipv6Addr;

#[inline]
fn not(mut self) -> Ipv6Addr {
for octet in &mut self.octets {
*octet = !*octet;
let mut idx = 0;
while idx < 16 {
self.octets[idx] = !self.octets[idx];
idx += 1;
}
self
}
}

#[stable(feature = "ip_bitops", since = "1.75.0")]
impl Not for &'_ Ipv6Addr {
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl const Not for &'_ Ipv6Addr {
type Output = Ipv6Addr;

#[inline]
Expand All @@ -2400,23 +2407,25 @@ macro_rules! bitop_impls {
)*) => {
$(
$(#[$attr])*
impl $BitOpAssign for $ty {
impl const $BitOpAssign for $ty {
fn $bitop_assign(&mut self, rhs: $ty) {
for (lhs, rhs) in iter::zip(&mut self.octets, rhs.octets) {
lhs.$bitop_assign(rhs);
let mut idx = 0;
while idx < self.octets.len() {
self.octets[idx].$bitop_assign(rhs.octets[idx]);
idx += 1;
}
}
}

$(#[$attr])*
impl $BitOpAssign<&'_ $ty> for $ty {
impl const $BitOpAssign<&'_ $ty> for $ty {
fn $bitop_assign(&mut self, rhs: &'_ $ty) {
self.$bitop_assign(*rhs);
}
}

$(#[$attr])*
impl $BitOp for $ty {
impl const $BitOp for $ty {
type Output = $ty;

#[inline]
Expand All @@ -2427,7 +2436,7 @@ macro_rules! bitop_impls {
}

$(#[$attr])*
impl $BitOp<&'_ $ty> for $ty {
impl const $BitOp<&'_ $ty> for $ty {
type Output = $ty;

#[inline]
Expand All @@ -2438,7 +2447,7 @@ macro_rules! bitop_impls {
}

$(#[$attr])*
impl $BitOp<$ty> for &'_ $ty {
impl const $BitOp<$ty> for &'_ $ty {
type Output = $ty;

#[inline]
Expand All @@ -2450,7 +2459,7 @@ macro_rules! bitop_impls {
}

$(#[$attr])*
impl $BitOp<&'_ $ty> for &'_ $ty {
impl const $BitOp<&'_ $ty> for &'_ $ty {
type Output = $ty;

#[inline]
Expand All @@ -2466,12 +2475,16 @@ macro_rules! bitop_impls {

bitop_impls! {
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl (BitAnd, BitAndAssign) for Ipv4Addr = (bitand, bitand_assign);
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl (BitOr, BitOrAssign) for Ipv4Addr = (bitor, bitor_assign);

#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl (BitAnd, BitAndAssign) for Ipv6Addr = (bitand, bitand_assign);
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
impl (BitOr, BitOrAssign) for Ipv6Addr = (bitor, bitor_assign);
}
Loading
Loading