Skip to content

Rollup of 4 pull requests #124301

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 47 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
e243f8d
Merge commit '89f54caacf90e99fc8ba0d60a28bdadea3cfdf1e' into sync_cg_…
bjorn3 Apr 11, 2024
bf02a87
Merge branch 'sync_from_rust'
bjorn3 Apr 11, 2024
71e7414
Allow MaybeUninit in input and output of inline assembly
taiki-e Apr 14, 2024
49ad3ae
Merge pull request #1481 from taiki-e/asm-maybe-uninit
bjorn3 Apr 14, 2024
5075386
Rustup to rustc 1.79.0-nightly (0d8b3346a 2024-04-14)
bjorn3 Apr 15, 2024
9e4e444
static_mut_refs: use raw pointers to remove the remaining FIXME
RalfJung Apr 15, 2024
ceead1b
Change intrinsic types to use `u32` instead of `T` to match stable re…
WaffleLapkin Apr 16, 2024
e4a854e
Miri: adopt to new intrinsic types
WaffleLapkin Apr 16, 2024
7ce867f
Add an assertion in const eval
WaffleLapkin Apr 16, 2024
c2046c4
Add codegen tests for changed intrinsics
WaffleLapkin Apr 16, 2024
4b6bbcb
Fixup 2 ui tests using changed intrinsics
WaffleLapkin Apr 16, 2024
fbac8ef
Cranelift: Revert raw-dylib for Windows futex APIs
ChrisDenton Apr 16, 2024
f532309
ScalarInt: add methods to assert being a (u)int of given size
RalfJung Apr 18, 2024
a2a949b
Auto merge of #124113 - RalfJung:interpret-scalar-ops, r=oli-obk
bors Apr 19, 2024
2ef1552
Don't fatal when calling expect_one_of when recovering arg in parse_seq
compiler-errors Apr 19, 2024
c0b5cc9
Do intrinsic changes in `rustc_codegen_cranelift`
WaffleLapkin Apr 19, 2024
468179c
Fixup `rustc_codegen_gcc` test signature
WaffleLapkin Apr 20, 2024
4027a52
Sync from rust f9b16149208c8a8a349c32813312716f6603eb6f
bjorn3 Apr 20, 2024
82dd93f
Rustup to rustc 1.79.0-nightly (f9b161492 2024-04-19)
bjorn3 Apr 20, 2024
9ad9620
Don't create data object for zero sized allocations
bjorn3 Apr 20, 2024
be9d7ca
Rollup merge of #123967 - RalfJung:static_mut_refs, r=Nilstrieb
jieyouxu Apr 20, 2024
72e6f0c
Remove a couple of items from the crate prelude
bjorn3 Apr 21, 2024
e654877
Also handle AggregateKind::RawPtr in cg_cranelift
scottmcm Apr 12, 2024
a74d6c2
Only apply --cap-lints to the extended_sysroot test suite
bjorn3 Apr 22, 2024
8bc15fb
Sync from rust fb898629a26e4acec59c928ce3ec00a62675d1cc
bjorn3 Apr 22, 2024
d0c5141
Rustup to rustc 1.79.0-nightly (fb898629a 2024-04-21)
bjorn3 Apr 22, 2024
8bf1687
Fix neon test on non arm64 targets
bjorn3 Apr 22, 2024
569df1d
Inline CValue::pointer_from_data_and_meta
bjorn3 Apr 22, 2024
498dbbd
Fix warning in alloc_system.rs
bjorn3 Apr 22, 2024
d569c84
Update libloading
bjorn3 Apr 22, 2024
c02f6c5
Update windows-trgets to 0.52.5
bjorn3 Apr 22, 2024
cea3e7d
Update syn, quote and proc-macro2
bjorn3 Apr 22, 2024
966e269
Update data structure crates
bjorn3 Apr 22, 2024
2c6ef5a
Update a couple of crates
bjorn3 Apr 22, 2024
6ec27fe
Update to Cranelift 0.107
bjorn3 Mar 31, 2024
041666a
Update abi-cafe ui128 test expectations
bjorn3 Apr 1, 2024
b8fdf71
Modify `find_expr` from `Span` to better account for closures
estebank Apr 18, 2024
0136766
Mention when type parameter could be `Clone`
estebank Apr 18, 2024
17a27e8
Suggest cloning captured binding in `move` closure
estebank Apr 19, 2024
de5d652
Rustup to rustc 1.79.0-nightly (7f2fc33da 2024-04-22)
bjorn3 Apr 23, 2024
3d682cf
Merge commit 'de5d6523738fd44a0521b6abf3e73ae1df210741' into sync_cg_…
bjorn3 Apr 23, 2024
7c968a2
Update allowed cg_clif deps
bjorn3 Apr 23, 2024
96152c7
Fix broken subtree sync
bjorn3 Apr 23, 2024
bbda9b6
Rollup merge of #124003 - WaffleLapkin:dellvmization, r=scottmcm,Ralf…
matthiaskrgr Apr 23, 2024
ba00abe
Rollup merge of #124136 - estebank:clone-o-rama-2, r=estebank
matthiaskrgr Apr 23, 2024
bba2788
Rollup merge of #124169 - compiler-errors:parser-fatal, r=oli-obk
matthiaskrgr Apr 23, 2024
7e9174d
Rollup merge of #124286 - bjorn3:sync_cg_clif-2024-04-23, r=bjorn3
matthiaskrgr Apr 23, 2024
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
55 changes: 46 additions & 9 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
mpi: MovePathIndex,
err: &mut Diag<'tcx>,
in_pattern: &mut bool,
move_spans: UseSpans<'_>,
move_spans: UseSpans<'tcx>,
) {
let move_span = match move_spans {
UseSpans::ClosureUse { capture_kind_span, .. } => capture_kind_span,
Expand Down Expand Up @@ -491,11 +491,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
..
} = move_spans
{
self.suggest_cloning(err, ty, expr, None);
self.suggest_cloning(err, ty, expr, None, Some(move_spans));
} else if self.suggest_hoisting_call_outside_loop(err, expr) {
// The place where the the type moves would be misleading to suggest clone.
// #121466
self.suggest_cloning(err, ty, expr, None);
self.suggest_cloning(err, ty, expr, None, Some(move_spans));
}
}
if let Some(pat) = finder.pat {
Expand Down Expand Up @@ -1085,6 +1085,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
ty: Ty<'tcx>,
mut expr: &'cx hir::Expr<'cx>,
mut other_expr: Option<&'cx hir::Expr<'cx>>,
use_spans: Option<UseSpans<'tcx>>,
) {
if let hir::ExprKind::Struct(_, _, Some(_)) = expr.kind {
// We have `S { foo: val, ..base }`. In `check_aggregate_rvalue` we have a single
Expand Down Expand Up @@ -1197,14 +1198,50 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
.all(|field| self.implements_clone(field.ty(self.infcx.tcx, args)))
})
{
let ty_span = self.infcx.tcx.def_span(def.did());
let mut span: MultiSpan = ty_span.into();
span.push_span_label(ty_span, "consider implementing `Clone` for this type");
span.push_span_label(expr.span, "you could clone this value");
err.span_note(
self.infcx.tcx.def_span(def.did()),
span,
format!("if `{ty}` implemented `Clone`, you could clone the value"),
);
} else if let ty::Param(param) = ty.kind()
&& let Some(_clone_trait_def) = self.infcx.tcx.lang_items().clone_trait()
&& let generics = self.infcx.tcx.generics_of(self.mir_def_id())
&& let generic_param = generics.type_param(&param, self.infcx.tcx)
&& let param_span = self.infcx.tcx.def_span(generic_param.def_id)
&& if let Some(UseSpans::FnSelfUse { kind, .. }) = use_spans
&& let CallKind::FnCall { fn_trait_id, self_ty } = kind
&& let ty::Param(_) = self_ty.kind()
&& ty == self_ty
&& [
self.infcx.tcx.lang_items().fn_once_trait(),
self.infcx.tcx.lang_items().fn_mut_trait(),
self.infcx.tcx.lang_items().fn_trait(),
]
.contains(&Some(fn_trait_id))
{
// Do not suggest `F: FnOnce() + Clone`.
false
} else {
true
}
{
let mut span: MultiSpan = param_span.into();
span.push_span_label(
param_span,
"consider constraining this type parameter with `Clone`",
);
span.push_span_label(expr.span, "you could clone this value");
err.span_help(
span,
format!("if `{ty}` implemented `Clone`, you could clone the value"),
);
}
}

fn implements_clone(&self, ty: Ty<'tcx>) -> bool {
pub(crate) fn implements_clone(&self, ty: Ty<'tcx>) -> bool {
let Some(clone_trait_def) = self.infcx.tcx.lang_items().clone_trait() else { return false };
self.infcx
.type_implements_trait(clone_trait_def, [ty], self.param_env)
Expand Down Expand Up @@ -1403,7 +1440,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let Some(expr) = self.find_expr(borrow_span)
&& let Some(ty) = typeck_results.node_type_opt(expr.hir_id)
{
self.suggest_cloning(&mut err, ty, expr, self.find_expr(span));
self.suggest_cloning(&mut err, ty, expr, self.find_expr(span), Some(move_spans));
}
self.buffer_error(err);
}
Expand Down Expand Up @@ -1955,7 +1992,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
pub(crate) fn find_expr(&self, span: Span) -> Option<&hir::Expr<'_>> {
let tcx = self.infcx.tcx;
let body_id = tcx.hir_node(self.mir_hir_id()).body_id()?;
let mut expr_finder = FindExprBySpan::new(span);
let mut expr_finder = FindExprBySpan::new(span, tcx);
expr_finder.visit_expr(tcx.hir().body(body_id).value);
expr_finder.result
}
Expand Down Expand Up @@ -1989,14 +2026,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
};

let mut expr_finder =
FindExprBySpan::new(self.body.local_decls[*index1].source_info.span);
FindExprBySpan::new(self.body.local_decls[*index1].source_info.span, tcx);
expr_finder.visit_expr(hir.body(body_id).value);
let Some(index1) = expr_finder.result else {
note_default_suggestion();
return;
};

expr_finder = FindExprBySpan::new(self.body.local_decls[*index2].source_info.span);
expr_finder = FindExprBySpan::new(self.body.local_decls[*index2].source_info.span, tcx);
expr_finder.visit_expr(hir.body(body_id).value);
let Some(index2) = expr_finder.result else {
note_default_suggestion();
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
&& let Some(body_id) = node.body_id()
{
let body = tcx.hir().body(body_id);
let mut expr_finder = FindExprBySpan::new(span);
let mut expr_finder = FindExprBySpan::new(span, tcx);
expr_finder.visit_expr(body.value);
if let Some(mut expr) = expr_finder.result {
while let hir::ExprKind::AddrOf(_, _, inner)
Expand Down
154 changes: 144 additions & 10 deletions compiler/rustc_borrowck/src/diagnostics/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
#![allow(rustc::untranslatable_diagnostic)]

use rustc_errors::{Applicability, Diag};
use rustc_hir::intravisit::Visitor;
use rustc_hir::{CaptureBy, ExprKind, HirId, Node};
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty};
use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex};
use rustc_span::{BytePos, ExpnKind, MacroKind, Span};
use rustc_trait_selection::traits::error_reporting::FindExprBySpan;

use crate::diagnostics::CapturedMessageOpt;
use crate::diagnostics::{DescribePlaceOpt, UseSpans};
Expand Down Expand Up @@ -303,17 +306,133 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
self.cannot_move_out_of(span, &description)
}

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;
expr_finder.visit_expr(tcx.hir().body(body_id).value);
let Some(closure_expr) = expr_finder.result else { return };
let ExprKind::Closure(closure) = closure_expr.kind else { return };
// We'll only suggest cloning the binding if it's a `move` closure.
let CaptureBy::Value { .. } = closure.capture_clause else { return };
// Find the expression within the closure where the binding is consumed.
let mut suggested = false;
let use_span = use_spans.var_or_use();
let mut expr_finder = FindExprBySpan::new(use_span, tcx);
expr_finder.include_closures = true;
expr_finder.visit_expr(tcx.hir().body(body_id).value);
let Some(use_expr) = expr_finder.result else { return };
let parent = tcx.parent_hir_node(use_expr.hir_id);
if let Node::Expr(expr) = parent
&& let ExprKind::Assign(lhs, ..) = expr.kind
&& lhs.hir_id == use_expr.hir_id
{
// Cloning the value being assigned makes no sense:
//
// error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
// --> $DIR/option-content-move2.rs:11:9
// |
// LL | let mut var = None;
// | ------- captured outer variable
// LL | func(|| {
// | -- captured by this `FnMut` closure
// LL | // Shouldn't suggest `move ||.as_ref()` here
// LL | move || {
// | ^^^^^^^ `var` is moved here
// LL |
// LL | var = Some(NotCopyable);
// | ---
// | |
// | variable moved due to use in closure
// | move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
// |
return;
}

// Search for an appropriate place for the structured `.clone()` suggestion to be applied.
// If we encounter a statement before the borrow error, we insert a statement there.
for (_, node) in tcx.hir().parent_iter(closure_expr.hir_id) {
if let Node::Stmt(stmt) = node {
let padding = tcx
.sess
.source_map()
.indentation_before(stmt.span)
.unwrap_or_else(|| " ".to_string());
err.multipart_suggestion_verbose(
"clone the value before moving it into the closure",
vec![
(
stmt.span.shrink_to_lo(),
format!("let value = {upvar_name}.clone();\n{padding}"),
),
(use_span, "value".to_string()),
],
Applicability::MachineApplicable,
);
suggested = true;
break;
} else if let Node::Expr(expr) = node
&& let ExprKind::Closure(_) = expr.kind
{
// We want to suggest cloning only on the first closure, not
// subsequent ones (like `ui/suggestions/option-content-move2.rs`).
break;
}
}
if !suggested {
// If we couldn't find a statement for us to insert a new `.clone()` statement before,
// we have a bare expression, so we suggest the creation of a new block inline to go
// from `move || val` to `{ let value = val.clone(); move || value }`.
let padding = tcx
.sess
.source_map()
.indentation_before(closure_expr.span)
.unwrap_or_else(|| " ".to_string());
err.multipart_suggestion_verbose(
"clone the value before moving it into the closure",
vec![
(
closure_expr.span.shrink_to_lo(),
format!("{{\n{padding}let value = {upvar_name}.clone();\n{padding}"),
),
(use_spans.var_or_use(), "value".to_string()),
(closure_expr.span.shrink_to_hi(), format!("\n{padding}}}")),
],
Applicability::MachineApplicable,
);
}
}

fn report_cannot_move_from_borrowed_content(
&mut self,
move_place: Place<'tcx>,
deref_target_place: Place<'tcx>,
span: Span,
use_spans: Option<UseSpans<'tcx>>,
) -> Diag<'tcx> {
let tcx = self.infcx.tcx;
// Inspect the type of the content behind the
// borrow to provide feedback about why this
// was a move rather than a copy.
let ty = deref_target_place.ty(self.body, self.infcx.tcx).ty;
let ty = deref_target_place.ty(self.body, tcx).ty;
let upvar_field = self
.prefixes(move_place.as_ref(), PrefixSet::All)
.find_map(|p| self.is_upvar_field_projection(p));
Expand Down Expand Up @@ -363,8 +482,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {

let upvar = &self.upvars[upvar_field.unwrap().index()];
let upvar_hir_id = upvar.get_root_variable();
let upvar_name = upvar.to_string(self.infcx.tcx);
let upvar_span = self.infcx.tcx.hir().span(upvar_hir_id);
let upvar_name = upvar.to_string(tcx);
let upvar_span = tcx.hir().span(upvar_hir_id);

let place_name = self.describe_any_place(move_place.as_ref());

Expand All @@ -380,12 +499,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
closure_kind_ty, closure_kind, place_description,
);

self.cannot_move_out_of(span, &place_description)
let closure_span = tcx.def_span(def_id);
let mut err = self
.cannot_move_out_of(span, &place_description)
.with_span_label(upvar_span, "captured outer variable")
.with_span_label(
self.infcx.tcx.def_span(def_id),
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 @@ -415,7 +543,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
),
(_, _, _) => self.cannot_move_out_of(
span,
&source.describe_for_unnamed_place(self.infcx.tcx),
&source.describe_for_unnamed_place(tcx),
),
}
}
Expand Down Expand Up @@ -447,7 +575,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};

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

err.subdiagnostic(
Expand Down Expand Up @@ -482,7 +610,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};

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

err.subdiagnostic(
Expand Down Expand Up @@ -595,7 +729,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let place_desc = &format!("`{}`", self.local_names[*local].unwrap());

if let Some(expr) = self.find_expr(binding_span) {
self.suggest_cloning(err, bind_to.ty, expr, None);
self.suggest_cloning(err, bind_to.ty, expr, None, None);
}

err.subdiagnostic(
Expand Down
Loading
Loading