summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_borrowck/src/diagnostics
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /compiler/rustc_borrowck/src/diagnostics
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_borrowck/src/diagnostics')
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs41
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs165
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs14
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs27
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs40
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs8
7 files changed, 205 insertions, 92 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index f41795d60..cfcf31fce 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -180,24 +180,25 @@ trait TypeOpInfo<'tcx> {
return;
};
- let placeholder_region = tcx.mk_re_placeholder(ty::Placeholder {
- universe: adjusted_universe.into(),
- bound: placeholder.bound,
- });
-
- let error_region =
- if let RegionElement::PlaceholderRegion(error_placeholder) = error_element {
- let adjusted_universe =
- error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
- adjusted_universe.map(|adjusted| {
- tcx.mk_re_placeholder(ty::Placeholder {
- universe: adjusted.into(),
- bound: error_placeholder.bound,
- })
- })
- } else {
- None
- };
+ let placeholder_region = ty::Region::new_placeholder(
+ tcx,
+ ty::Placeholder { universe: adjusted_universe.into(), bound: placeholder.bound },
+ );
+
+ let error_region = if let RegionElement::PlaceholderRegion(error_placeholder) =
+ error_element
+ {
+ let adjusted_universe =
+ error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
+ adjusted_universe.map(|adjusted| {
+ ty::Region::new_placeholder(
+ tcx,
+ ty::Placeholder { universe: adjusted.into(), bound: error_placeholder.bound },
+ )
+ })
+ } else {
+ None
+ };
debug!(?placeholder_region);
@@ -390,7 +391,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
error_region,
&region_constraints,
|vid| ocx.infcx.region_var_origin(vid),
- |vid| ocx.infcx.universe_of_region(ocx.infcx.tcx.mk_re_var(vid)),
+ |vid| ocx.infcx.universe_of_region(ty::Region::new_var(ocx.infcx.tcx, vid)),
)
}
@@ -411,7 +412,7 @@ fn try_extract_error_from_region_constraints<'tcx>(
}
// FIXME: Should this check the universe of the var?
Constraint::VarSubReg(vid, sup) if sup == placeholder_region => {
- Some((infcx.tcx.mk_re_var(vid), cause.clone()))
+ Some((ty::Region::new_var(infcx.tcx, vid), cause.clone()))
}
_ => None,
}
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 15d73ed73..c8c8b72b3 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1,6 +1,5 @@
-use std::iter;
-
use either::Either;
+use hir::PatField;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{
@@ -14,9 +13,10 @@ use rustc_infer::traits::ObligationCause;
use rustc_middle::hir::nested_filter::OnlyBodies;
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::{
- self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
- FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
- ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
+ self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory,
+ FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind, Operand, Place,
+ PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
+ VarBindingForm,
};
use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty};
use rustc_middle::util::CallKind;
@@ -27,6 +27,7 @@ use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::ObligationCtxt;
+use std::iter;
use crate::borrow_set::TwoPhaseActivation;
use crate::borrowck_errors;
@@ -677,8 +678,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let tcx = self.infcx.tcx;
// Find out if the predicates show that the type is a Fn or FnMut
- let find_fn_kind_from_did = |(pred, _): (ty::Predicate<'tcx>, _)| {
- if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = pred.kind().skip_binder()
+ let find_fn_kind_from_did = |(pred, _): (ty::Clause<'tcx>, _)| {
+ if let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder()
&& pred.self_ty() == ty
{
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
@@ -704,7 +705,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx
.explicit_item_bounds(def_id)
.subst_iter_copied(tcx, substs)
- .find_map(find_fn_kind_from_did),
+ .find_map(|(clause, span)| find_fn_kind_from_did((clause, span))),
ty::Closure(_, substs) => match substs.as_closure().kind() {
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),
@@ -775,7 +776,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let predicates: Result<Vec<_>, _> = errors
.into_iter()
.map(|err| match err.obligation.predicate.kind().skip_binder() {
- PredicateKind::Clause(ty::Clause::Trait(predicate)) => {
+ PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
match predicate.self_ty().kind() {
ty::Param(param_ty) => Ok((
generics.type_param(param_ty, tcx),
@@ -926,7 +927,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// FIXME: supply non-"" `opt_via` when appropriate
let first_borrow_desc;
let mut err = match (gen_borrow_kind, issued_borrow.kind) {
- (BorrowKind::Shared, BorrowKind::Mut { .. }) => {
+ (
+ BorrowKind::Shared,
+ BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
+ ) => {
first_borrow_desc = "mutable ";
self.cannot_reborrow_already_borrowed(
span,
@@ -940,7 +944,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
None,
)
}
- (BorrowKind::Mut { .. }, BorrowKind::Shared) => {
+ (
+ BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
+ BorrowKind::Shared,
+ ) => {
first_borrow_desc = "immutable ";
let mut err = self.cannot_reborrow_already_borrowed(
span,
@@ -962,7 +969,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
err
}
- (BorrowKind::Mut { .. }, BorrowKind::Mut { .. }) => {
+ (
+ BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
+ BorrowKind::Mut { kind: MutBorrowKind::Default | MutBorrowKind::TwoPhaseBorrow },
+ ) => {
first_borrow_desc = "first ";
let mut err = self.cannot_mutably_borrow_multiply(
span,
@@ -972,7 +982,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&msg_borrow,
None,
);
- self.suggest_split_at_mut_if_applicable(
+ self.suggest_slice_method_if_applicable(
&mut err,
place,
issued_borrow.borrowed_place,
@@ -982,15 +992,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
issued_borrow.borrowed_place,
&issued_spans,
);
+ self.explain_iterator_advancement_in_for_loop_if_applicable(
+ &mut err,
+ span,
+ &issued_spans,
+ );
err
}
- (BorrowKind::Unique, BorrowKind::Unique) => {
+ (
+ BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture },
+ BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture },
+ ) => {
first_borrow_desc = "first ";
self.cannot_uniquely_borrow_by_two_closures(span, &desc_place, issued_span, None)
}
- (BorrowKind::Mut { .. } | BorrowKind::Unique, BorrowKind::Shallow) => {
+ (BorrowKind::Mut { .. }, BorrowKind::Shallow) => {
if let Some(immutable_section_description) =
self.classify_immutable_section(issued_borrow.assigned_place)
{
@@ -1004,7 +1022,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
borrow_spans.var_subdiag(
None,
&mut err,
- Some(BorrowKind::Unique),
+ Some(BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }),
|kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*;
match kind {
@@ -1038,7 +1056,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
- (BorrowKind::Unique, _) => {
+ (BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }, _) => {
first_borrow_desc = "first ";
self.cannot_uniquely_borrow_by_one_closure(
span,
@@ -1052,7 +1070,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
)
}
- (BorrowKind::Shared, BorrowKind::Unique) => {
+ (BorrowKind::Shared, BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }) => {
first_borrow_desc = "first ";
self.cannot_reborrow_already_uniquely_borrowed(
span,
@@ -1067,7 +1085,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
)
}
- (BorrowKind::Mut { .. }, BorrowKind::Unique) => {
+ (BorrowKind::Mut { .. }, BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }) => {
first_borrow_desc = "first ";
self.cannot_reborrow_already_uniquely_borrowed(
span,
@@ -1085,10 +1103,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
(BorrowKind::Shared, BorrowKind::Shared | BorrowKind::Shallow)
| (
BorrowKind::Shallow,
- BorrowKind::Mut { .. }
- | BorrowKind::Unique
- | BorrowKind::Shared
- | BorrowKind::Shallow,
+ BorrowKind::Mut { .. } | BorrowKind::Shared | BorrowKind::Shallow,
) => unreachable!(),
};
@@ -1252,7 +1267,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
}
- fn suggest_split_at_mut_if_applicable(
+ fn suggest_slice_method_if_applicable(
&self,
err: &mut Diagnostic,
place: Place<'tcx>,
@@ -1264,7 +1279,75 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
err.help(
"consider using `.split_at_mut(position)` or similar method to obtain \
two mutable non-overlapping sub-slices",
- );
+ )
+ .help("consider using `.swap(index_1, index_2)` to swap elements at the specified indices");
+ }
+ }
+
+ /// Suggest using `while let` for call `next` on an iterator in a for loop.
+ ///
+ /// For example:
+ /// ```ignore (illustrative)
+ ///
+ /// for x in iter {
+ /// ...
+ /// iter.next()
+ /// }
+ /// ```
+ pub(crate) fn explain_iterator_advancement_in_for_loop_if_applicable(
+ &self,
+ err: &mut Diagnostic,
+ span: Span,
+ issued_spans: &UseSpans<'tcx>,
+ ) {
+ let issue_span = issued_spans.args_or_use();
+ let tcx = self.infcx.tcx;
+ let hir = tcx.hir();
+
+ let Some(body_id) = hir.get(self.mir_hir_id()).body_id() else { return };
+ let typeck_results = tcx.typeck(self.mir_def_id());
+
+ struct ExprFinder<'hir> {
+ issue_span: Span,
+ expr_span: Span,
+ body_expr: Option<&'hir hir::Expr<'hir>>,
+ loop_bind: Option<Symbol>,
+ }
+ impl<'hir> Visitor<'hir> for ExprFinder<'hir> {
+ fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) {
+ if let hir::ExprKind::Loop(hir::Block{ stmts: [stmt, ..], ..}, _, hir::LoopSource::ForLoop, _) = ex.kind &&
+ let hir::StmtKind::Expr(hir::Expr{ kind: hir::ExprKind::Match(call, [_, bind, ..], _), ..}) = stmt.kind &&
+ let hir::ExprKind::Call(path, _args) = call.kind &&
+ let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IteratorNext, _, _, )) = path.kind &&
+ let hir::PatKind::Struct(path, [field, ..], _) = bind.pat.kind &&
+ let hir::QPath::LangItem(LangItem::OptionSome, _, _) = path &&
+ let PatField { pat: hir::Pat{ kind: hir::PatKind::Binding(_, _, ident, ..), .. }, ..} = field &&
+ self.issue_span.source_equal(call.span) {
+ self.loop_bind = Some(ident.name);
+ }
+
+ if let hir::ExprKind::MethodCall(body_call, _recv, ..) = ex.kind &&
+ body_call.ident.name == sym::next && ex.span.source_equal(self.expr_span) {
+ self.body_expr = Some(ex);
+ }
+
+ hir::intravisit::walk_expr(self, ex);
+ }
+ }
+ let mut finder =
+ ExprFinder { expr_span: span, issue_span, loop_bind: None, body_expr: None };
+ finder.visit_expr(hir.body(body_id).value);
+
+ if let Some(loop_bind) = finder.loop_bind &&
+ let Some(body_expr) = finder.body_expr &&
+ let Some(def_id) = typeck_results.type_dependent_def_id(body_expr.hir_id) &&
+ let Some(trait_did) = tcx.trait_of_item(def_id) &&
+ tcx.is_diagnostic_item(sym::Iterator, trait_did) {
+ err.note(format!(
+ "a for loop advances the iterator for you, the result is stored in `{}`.",
+ loop_bind
+ ));
+ err.help("if you want to call `next` on a iterator within the loop, consider using `while let`.");
}
}
@@ -1720,18 +1803,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
(
Some(name),
BorrowExplanation::UsedLater(LaterUseKind::ClosureCapture, var_or_use_span, _),
- ) => self.report_escaping_closure_capture(
- borrow_spans,
- borrow_span,
- &RegionName {
- name: self.synthesize_region_name(),
- source: RegionNameSource::Static,
- },
- ConstraintCategory::CallArgument(None),
- var_or_use_span,
- &format!("`{}`", name),
- "block",
- ),
+ ) if borrow_spans.for_generator() || borrow_spans.for_closure() => self
+ .report_escaping_closure_capture(
+ borrow_spans,
+ borrow_span,
+ &RegionName {
+ name: self.synthesize_region_name(),
+ source: RegionNameSource::Static,
+ },
+ ConstraintCategory::CallArgument(None),
+ var_or_use_span,
+ &format!("`{}`", name),
+ "block",
+ ),
(
Some(name),
BorrowExplanation::MustBeValidFor {
@@ -1744,7 +1828,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
span,
..
},
- ) if borrow_spans.for_generator() | borrow_spans.for_closure() => self
+ ) if borrow_spans.for_generator() || borrow_spans.for_closure() => self
.report_escaping_closure_capture(
borrow_spans,
borrow_span,
@@ -2579,7 +2663,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut Diagnostic) {
let tcx = self.infcx.tcx;
if let (
- Some(Terminator { kind: TerminatorKind::Call { from_hir_call: false, .. }, .. }),
+ Some(Terminator {
+ kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. },
+ ..
+ }),
Some((method_did, method_substs)),
) = (
&self.body[loan.reserve_location.block].terminator,
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 1d430a93a..225c38efb 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -6,10 +6,10 @@ use rustc_hir::intravisit::Visitor;
use rustc_index::IndexSlice;
use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_middle::mir::{
- Body, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location, Operand, Place,
- Rvalue, Statement, StatementKind, TerminatorKind,
+ Body, CallSource, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location,
+ Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind,
};
-use rustc_middle::ty::adjustment::PointerCast;
+use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::{self, RegionVid, TyCtxt};
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{sym, DesugaringKind, Span};
@@ -494,7 +494,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} else if self.was_captured_by_trait_object(borrow) {
LaterUseKind::TraitCapture
} else if location.statement_index == block.statements.len() {
- if let TerminatorKind::Call { func, from_hir_call: true, .. } =
+ if let TerminatorKind::Call { func, call_source: CallSource::Normal, .. } =
&block.terminator().kind
{
// Just point to the function, to reduce the chance of overlapping spans.
@@ -584,7 +584,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
},
// If we see an unsized cast, then if it is our data we should check
// whether it is being cast to a trait object.
- Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), operand, ty) => {
+ Rvalue::Cast(
+ CastKind::PointerCoercion(PointerCoercion::Unsize),
+ operand,
+ ty,
+ ) => {
match operand {
Operand::Copy(place) | Operand::Move(place) => {
if let Some(from) = place.as_local() {
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 20370e4c6..d292611e6 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -13,8 +13,9 @@ use rustc_index::IndexSlice;
use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::{
- AggregateKind, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location, Operand, Place,
- PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
+ AggregateKind, CallSource, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location,
+ Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
+ TerminatorKind,
};
use rustc_middle::ty::print::Print;
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
@@ -414,7 +415,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if !is_terminator {
continue;
} else if let Some(Terminator {
- kind: TerminatorKind::Call { func, from_hir_call: false, .. },
+ kind:
+ TerminatorKind::Call {
+ func,
+ call_source: CallSource::OverloadedOperator,
+ ..
+ },
..
}) = &bbd.terminator
{
@@ -622,8 +628,7 @@ impl UseSpans<'_> {
err.subdiagnostic(match kind {
Some(kd) => match kd {
rustc_middle::mir::BorrowKind::Shared
- | rustc_middle::mir::BorrowKind::Shallow
- | rustc_middle::mir::BorrowKind::Unique => {
+ | rustc_middle::mir::BorrowKind::Shallow => {
CaptureVarKind::Immut { kind_span: capture_kind_span }
}
@@ -839,7 +844,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
debug!("move_spans: target_temp = {:?}", target_temp);
if let Some(Terminator {
- kind: TerminatorKind::Call { fn_span, from_hir_call, .. }, ..
+ kind: TerminatorKind::Call { fn_span, call_source, .. }, ..
}) = &self.body[location.block].terminator
{
let Some((method_did, method_substs)) =
@@ -859,7 +864,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
method_did,
method_substs,
*fn_span,
- *from_hir_call,
+ call_source.from_hir_call(),
Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
);
@@ -1045,7 +1050,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Some(def_id) => type_known_to_meet_bound_modulo_regions(
&self.infcx,
self.param_env,
- tcx.mk_imm_ref(tcx.lifetimes.re_erased, ty),
+ Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, ty),
def_id,
),
_ => false,
@@ -1141,6 +1146,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// Avoid pointing to the same function in multiple different
// error messages.
if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span) {
+ self.explain_iterator_advancement_in_for_loop_if_applicable(
+ err,
+ span,
+ &move_spans,
+ );
+
let func = tcx.def_path_str(method_did);
err.subdiagnostic(CaptureReasonNote::FuncTakeSelf {
func,
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index d0e17bf5a..1f2fefadf 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -123,13 +123,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
item_msg = access_place_desc;
debug_assert!(self.body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty.is_ref());
debug_assert!(is_closure_or_generator(
- Place::ty_from(
- the_place_err.local,
- the_place_err.projection,
- self.body,
- self.infcx.tcx
- )
- .ty
+ the_place_err.ty(self.body, self.infcx.tcx).ty
));
reason = if self.is_upvar_field_projection(access_place.as_ref()).is_some() {
@@ -234,7 +228,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
borrow_spans.var_subdiag(
None,
&mut err,
- Some(mir::BorrowKind::Mut { allow_two_phase_borrow: false }),
+ Some(mir::BorrowKind::Mut { kind: mir::MutBorrowKind::Default }),
|_kind, var_span| {
let place = self.describe_any_place(access_place.as_ref());
crate::session_diagnostics::CaptureVarCause::MutableBorrowUsePlaceClosure {
@@ -300,7 +294,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
_,
mir::Rvalue::Ref(
_,
- mir::BorrowKind::Mut { allow_two_phase_borrow: false },
+ mir::BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
_,
),
)),
@@ -416,12 +410,28 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
_,
) = pat.kind
{
- err.span_suggestion(
- upvar_ident.span,
- "consider changing this to be mutable",
- format!("mut {}", upvar_ident.name),
- Applicability::MachineApplicable,
- );
+ if upvar_ident.name == kw::SelfLower {
+ for (_, node) in self.infcx.tcx.hir().parent_iter(upvar_hir_id) {
+ if let Some(fn_decl) = node.fn_decl() {
+ if !matches!(fn_decl.implicit_self, hir::ImplicitSelfKind::ImmRef | hir::ImplicitSelfKind::MutRef) {
+ err.span_suggestion(
+ upvar_ident.span,
+ "consider changing this to be mutable",
+ format!("mut {}", upvar_ident.name),
+ Applicability::MachineApplicable,
+ );
+ break;
+ }
+ }
+ }
+ } else {
+ err.span_suggestion(
+ upvar_ident.span,
+ "consider changing this to be mutable",
+ format!("mut {}", upvar_ident.name),
+ Applicability::MachineApplicable,
+ );
+ }
}
let tcx = self.infcx.tcx;
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 8ec872e20..617c85174 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -508,7 +508,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let generic_arg = substs[param_index as usize];
let identity_substs =
InternalSubsts::identity_for_item(self.infcx.tcx, adt.did());
- let base_ty = self.infcx.tcx.mk_adt(*adt, identity_substs);
+ let base_ty = Ty::new_adt(self.infcx.tcx, *adt, identity_substs);
let base_generic_arg = identity_substs[param_index as usize];
let adt_desc = adt.descr();
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index f38e1605f..074f37bed 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -928,7 +928,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
fn any_param_predicate_mentions(
&self,
- predicates: &[ty::Predicate<'tcx>],
+ clauses: &[ty::Clause<'tcx>],
ty: Ty<'tcx>,
region: ty::EarlyBoundRegion,
) -> bool {
@@ -937,10 +937,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Param(_) = ty.kind()
{
- predicates.iter().any(|pred| {
+ clauses.iter().any(|pred| {
match pred.kind().skip_binder() {
- ty::PredicateKind::Clause(ty::Clause::Trait(data)) if data.self_ty() == ty => {}
- ty::PredicateKind::Clause(ty::Clause::Projection(data)) if data.projection_ty.self_ty() == ty => {}
+ ty::ClauseKind::Trait(data) if data.self_ty() == ty => {}
+ ty::ClauseKind::Projection(data) if data.projection_ty.self_ty() == ty => {}
_ => return false,
}
tcx.any_free_region_meets(pred, |r| {