Skip to content

Rollup of 9 pull requests #143042

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

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e40515a
add method to retrieve body of coroutine
makai410 Jun 22, 2025
7e683cc
Do not emit `redundant_explicit_links` rustdoc lint if the doc commen…
GuillaumeGomez May 27, 2025
a0d6417
Add ui test for `redundant_explicit_links` rustdoc lint for items com…
GuillaumeGomez May 27, 2025
987c2ff
Update clippy source code to changes on `source_span_for_markdown_range`
GuillaumeGomez May 27, 2025
78cbcaf
Update tests to work with new DocFragment field and `redundant_explic…
GuillaumeGomez Jun 3, 2025
3b5525b
Improve code and documentation
GuillaumeGomez Jun 10, 2025
904652b
Suggest cloning `Arc` moved into closure
estebank May 1, 2024
250b5d2
Make missing lifetime suggestion verbose
compiler-errors Jun 24, 2025
8cd3fa0
Don't give APITs names with macro expansion placeholder fragments in it
compiler-errors Jun 18, 2025
2338821
tests: Do not run afoul of asm.validity.non-exhaustive in input-stats
workingjubilee Jun 11, 2025
1dfc840
make `tidy-alphabetical` use a natural sort
folkertdev May 20, 2025
05d3d17
Fix suggestion spans inside macros for the `unused_must_use` lint
Urgau Jun 25, 2025
3175fb2
Bless `tests/ui/macros/must-use-in-macro-55516.rs`
Urgau Jun 25, 2025
59e1a3c
Simplify IfCause
compiler-errors Jun 25, 2025
53cd91d
Rollup merge of #124595 - estebank:issue-104232, r=davidtwco
matthiaskrgr Jun 26, 2025
9ba2b15
Rollup merge of #139594 - compiler-errors:if-cause, r=oli-obk
matthiaskrgr Jun 26, 2025
1cb41f2
Rollup merge of #141311 - folkertdev:tidy-natural-sort, r=jieyouxu
matthiaskrgr Jun 26, 2025
93d6e5b
Rollup merge of #141648 - GuillaumeGomez:redundant_explicit_links-exp…
matthiaskrgr Jun 26, 2025
2b4cee6
Rollup merge of #142285 - workingjubilee:dont-use-bad-assembly, r=nne…
matthiaskrgr Jun 26, 2025
ceeb84c
Rollup merge of #142393 - compiler-errors:nofield, r=petrochenkov
matthiaskrgr Jun 26, 2025
2730082
Rollup merge of #142884 - makai410:coroutine-body, r=celinval
matthiaskrgr Jun 26, 2025
a43d7cb
Rollup merge of #142981 - compiler-errors:verbose-missing-suggestion,…
matthiaskrgr Jun 26, 2025
ceaa5ea
Rollup merge of #143030 - Urgau:issue-143025, r=SparrowLii
matthiaskrgr Jun 26, 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
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4064,9 +4064,9 @@ mod size_asserts {
static_assert_size!(MetaItemLit, 40);
static_assert_size!(Param, 40);
static_assert_size!(Pat, 72);
static_assert_size!(PatKind, 48);
static_assert_size!(Path, 24);
static_assert_size!(PathSegment, 24);
static_assert_size!(PatKind, 48);
static_assert_size!(Stmt, 32);
static_assert_size!(StmtKind, 16);
static_assert_size!(Ty, 64);
Expand Down
17 changes: 12 additions & 5 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,11 +518,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
} = move_spans
&& can_suggest_clone
{
self.suggest_cloning(err, ty, expr, Some(move_spans));
self.suggest_cloning(err, place.as_ref(), ty, expr, Some(move_spans));
} else if self.suggest_hoisting_call_outside_loop(err, expr) && can_suggest_clone {
// The place where the type moves would be misleading to suggest clone.
// #121466
self.suggest_cloning(err, ty, expr, Some(move_spans));
self.suggest_cloning(err, place.as_ref(), ty, expr, Some(move_spans));
}
}

Expand Down Expand Up @@ -1224,6 +1224,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
pub(crate) fn suggest_cloning(
&self,
err: &mut Diag<'_>,
place: PlaceRef<'tcx>,
ty: Ty<'tcx>,
expr: &'tcx hir::Expr<'tcx>,
use_spans: Option<UseSpans<'tcx>>,
Expand All @@ -1238,7 +1239,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
}

if self.implements_clone(ty) {
self.suggest_cloning_inner(err, ty, expr);
if self.in_move_closure(expr) {
if let Some(name) = self.describe_place(place) {
self.suggest_clone_of_captured_var_in_move_closure(err, &name, use_spans);
}
} else {
self.suggest_cloning_inner(err, ty, expr);
}
} else if let ty::Adt(def, args) = ty.kind()
&& def.did().as_local().is_some()
&& def.variants().iter().all(|variant| {
Expand Down Expand Up @@ -1505,7 +1512,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if let hir::ExprKind::AddrOf(_, _, borrowed_expr) = expr.kind
&& let Some(ty) = typeck_results.expr_ty_opt(borrowed_expr)
{
self.suggest_cloning(&mut err, ty, borrowed_expr, Some(move_spans));
self.suggest_cloning(&mut err, place.as_ref(), ty, borrowed_expr, Some(move_spans));
} else if typeck_results.expr_adjustments(expr).first().is_some_and(|adj| {
matches!(
adj.kind,
Expand All @@ -1518,7 +1525,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
)
}) && let Some(ty) = typeck_results.expr_ty_opt(expr)
{
self.suggest_cloning(&mut err, ty, expr, Some(move_spans));
self.suggest_cloning(&mut err, place.as_ref(), ty, expr, Some(move_spans));
}
}
self.buffer_error(err);
Expand Down
39 changes: 15 additions & 24 deletions compiler/rustc_borrowck/src/diagnostics/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,25 +325,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
self.cannot_move_out_of(span, &description)
}

fn suggest_clone_of_captured_var_in_move_closure(
pub(in crate::diagnostics) fn suggest_clone_of_captured_var_in_move_closure(
&self,
err: &mut Diag<'_>,
upvar_hir_id: HirId,
upvar_name: &str,
use_spans: Option<UseSpans<'tcx>>,
) {
let tcx = self.infcx.tcx;
let typeck_results = tcx.typeck(self.mir_def_id());
let Some(use_spans) = use_spans else { return };
// We only care about the case where a closure captured a binding.
let UseSpans::ClosureUse { args_span, .. } = use_spans else { return };
let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return };
// Fetch the type of the expression corresponding to the closure-captured binding.
let Some(captured_ty) = typeck_results.node_type_opt(upvar_hir_id) else { return };
if !self.implements_clone(captured_ty) {
// We only suggest cloning the captured binding if the type can actually be cloned.
return;
};
// Find the closure that captured the binding.
let mut expr_finder = FindExprBySpan::new(args_span, tcx);
expr_finder.include_closures = true;
Expand Down Expand Up @@ -396,7 +388,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
.indentation_before(stmt.span)
.unwrap_or_else(|| " ".to_string());
err.multipart_suggestion_verbose(
"clone the value before moving it into the closure",
"consider cloning the value before moving it into the closure",
vec![
(
stmt.span.shrink_to_lo(),
Expand Down Expand Up @@ -426,7 +418,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
.indentation_before(closure_expr.span)
.unwrap_or_else(|| " ".to_string());
err.multipart_suggestion_verbose(
"clone the value before moving it into the closure",
"consider cloning the value before moving it into the closure",
vec![
(
closure_expr.span.shrink_to_lo(),
Expand Down Expand Up @@ -523,20 +515,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
);

let closure_span = tcx.def_span(def_id);
let mut err = self
.cannot_move_out_of(span, &place_description)
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"),
);
self.suggest_clone_of_captured_var_in_move_closure(
&mut err,
upvar_hir_id,
&upvar_name,
use_spans,
);
err
)
}
_ => {
let source = self.borrowed_content_source(deref_base);
Expand Down Expand Up @@ -597,7 +581,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
};

if let Some(expr) = self.find_expr(span) {
self.suggest_cloning(err, place_ty, expr, None);
self.suggest_cloning(err, move_from.as_ref(), place_ty, expr, None);
}

err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
Expand Down Expand Up @@ -629,7 +613,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
};

if let Some(expr) = self.find_expr(use_span) {
self.suggest_cloning(err, place_ty, expr, Some(use_spans));
self.suggest_cloning(
err,
original_path.as_ref(),
place_ty,
expr,
Some(use_spans),
);
}

err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
Expand Down Expand Up @@ -832,7 +822,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let place_desc = self.local_name(*local).map(|sym| format!("`{sym}`"));

if let Some(expr) = self.find_expr(binding_span) {
self.suggest_cloning(err, bind_to.ty, expr, None);
let local_place: PlaceRef<'tcx> = (*local).into();
self.suggest_cloning(err, local_place, bind_to.ty, expr, None);
}

err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -878,9 +878,9 @@ mod size_asserts {

use super::*;
// tidy-alphabetical-start
static_assert_size!(Immediate, 48);
static_assert_size!(ImmTy<'_>, 64);
static_assert_size!(Operand, 56);
static_assert_size!(Immediate, 48);
static_assert_size!(OpTy<'_>, 72);
static_assert_size!(Operand, 56);
// tidy-alphabetical-end
}
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1056,9 +1056,9 @@ mod size_asserts {

use super::*;
// tidy-alphabetical-start
static_assert_size!(MPlaceTy<'_>, 64);
static_assert_size!(MemPlace, 48);
static_assert_size!(MemPlaceMeta, 24);
static_assert_size!(MPlaceTy<'_>, 64);
static_assert_size!(Place, 48);
static_assert_size!(PlaceTy<'_>, 64);
// tidy-alphabetical-end
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,10 @@ pub trait ResolverExpand {
trait_def_id: DefId,
impl_def_id: LocalDefId,
) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>;

/// Record the name of an opaque `Ty::ImplTrait` pre-expansion so that it can be used
/// to generate an item name later that does not reference placeholder macros.
fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol);
}

pub trait LintStoreExpand {
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1778,6 +1778,16 @@ impl InvocationCollectorNode for ast::Ty {
fragment.make_ty()
}
fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
// Save the pre-expanded name of this `ImplTrait`, so that later when defining
// an APIT we use a name that doesn't have any placeholder fragments in it.
if let ast::TyKind::ImplTrait(..) = self.kind {
// HACK: pprust breaks strings with newlines when the type
// gets too long. We don't want these to show up in compiler
// output or built artifacts, so replace them here...
// Perhaps we should instead format APITs more robustly.
let name = Symbol::intern(&pprust::ty_to_string(self).replace('\n', " "));
collector.cx.resolver.insert_impl_trait_name(self.id, name);
}
walk_ty(collector, self)
}
fn is_mac_call(&self) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4992,9 +4992,9 @@ mod size_asserts {
static_assert_size!(LetStmt<'_>, 72);
static_assert_size!(Param<'_>, 32);
static_assert_size!(Pat<'_>, 72);
static_assert_size!(PatKind<'_>, 48);
static_assert_size!(Path<'_>, 40);
static_assert_size!(PathSegment<'_>, 48);
static_assert_size!(PatKind<'_>, 48);
static_assert_size!(QPath<'_>, 24);
static_assert_size!(Res, 12);
static_assert_size!(Stmt<'_>, 32);
Expand Down
99 changes: 5 additions & 94 deletions compiler/rustc_hir_typeck/src/_match.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use rustc_errors::{Applicability, Diag};
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{self as hir, ExprKind, PatKind};
use rustc_hir::{self as hir, ExprKind, HirId, PatKind};
use rustc_hir_pretty::ty_to_string;
use rustc_middle::ty::{self, Ty};
use rustc_span::Span;
use rustc_trait_selection::traits::{
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
};
use tracing::{debug, instrument};

Expand Down Expand Up @@ -414,105 +414,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

pub(crate) fn if_cause(
&self,
span: Span,
cond_span: Span,
then_expr: &'tcx hir::Expr<'tcx>,
expr_id: HirId,
else_expr: &'tcx hir::Expr<'tcx>,
then_ty: Ty<'tcx>,
else_ty: Ty<'tcx>,
tail_defines_return_position_impl_trait: Option<LocalDefId>,
) -> ObligationCause<'tcx> {
let mut outer_span = if self.tcx.sess.source_map().is_multiline(span) {
// The `if`/`else` isn't in one line in the output, include some context to make it
// clear it is an if/else expression:
// ```
// LL | let x = if true {
// | _____________-
// LL || 10i32
// || ----- expected because of this
// LL || } else {
// LL || 10u32
// || ^^^^^ expected `i32`, found `u32`
// LL || };
// ||_____- `if` and `else` have incompatible types
// ```
Some(span)
} else {
// The entire expression is in one line, only point at the arms
// ```
// LL | let x = if true { 10i32 } else { 10u32 };
// | ----- ^^^^^ expected `i32`, found `u32`
// | |
// | expected because of this
// ```
None
};

let (error_sp, else_id) = if let ExprKind::Block(block, _) = &else_expr.kind {
let block = block.innermost_block();

// Avoid overlapping spans that aren't as readable:
// ```
// 2 | let x = if true {
// | _____________-
// 3 | | 3
// | | - expected because of this
// 4 | | } else {
// | |____________^
// 5 | ||
// 6 | || };
// | || ^
// | ||_____|
// | |______if and else have incompatible types
// | expected integer, found `()`
// ```
// by not pointing at the entire expression:
// ```
// 2 | let x = if true {
// | ------- `if` and `else` have incompatible types
// 3 | 3
// | - expected because of this
// 4 | } else {
// | ____________^
// 5 | |
// 6 | | };
// | |_____^ expected integer, found `()`
// ```
if block.expr.is_none()
&& block.stmts.is_empty()
&& let Some(outer_span) = &mut outer_span
&& let Some(cond_span) = cond_span.find_ancestor_inside(*outer_span)
{
*outer_span = outer_span.with_hi(cond_span.hi())
}

(self.find_block_span(block), block.hir_id)
} else {
(else_expr.span, else_expr.hir_id)
};

let then_id = if let ExprKind::Block(block, _) = &then_expr.kind {
let block = block.innermost_block();
// Exclude overlapping spans
if block.expr.is_none() && block.stmts.is_empty() {
outer_span = None;
}
block.hir_id
} else {
then_expr.hir_id
};
let error_sp = self.find_block_span_from_hir_id(else_expr.hir_id);

// Finally construct the cause:
self.cause(
error_sp,
ObligationCauseCode::IfExpression(Box::new(IfExpressionCause {
else_id,
then_id,
then_ty,
else_ty,
outer_span,
tail_defines_return_position_impl_trait,
})),
ObligationCauseCode::IfExpression { expr_id, tail_defines_return_position_impl_trait },
)
}

Expand Down
Loading
Loading