Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
58 changes: 32 additions & 26 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ use tracing::{debug, instrument};
use super::explain_borrow::{BorrowExplanation, LaterUseKind};
use super::{DescribePlaceOpt, RegionName, RegionNameSource, UseSpans};
use crate::borrow_set::{BorrowData, TwoPhaseActivation};
use crate::consumers::OutlivesConstraint;
use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
use crate::diagnostics::{CapturedMessageOpt, call_kind, find_all_local_uses};
use crate::{InitializationRequiringAction, MirBorrowckCtxt, WriteKind, borrowck_errors};
Expand Down Expand Up @@ -3076,40 +3077,48 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
),
(
Some(name),
BorrowExplanation::MustBeValidFor {
category:
category @ (ConstraintCategory::Return(_)
| ConstraintCategory::CallArgument(_)
| ConstraintCategory::OpaqueType),
from_closure: false,
ref region_name,
span,
..
},
) if borrow_spans.for_coroutine() || borrow_spans.for_closure() => self
.report_escaping_closure_capture(
BorrowExplanation::MustBeValidFor { ref region_name, ref best_blame, .. },
) if let OutlivesConstraint {
category:
category @ (ConstraintCategory::Return(_)
| ConstraintCategory::CallArgument(_)
| ConstraintCategory::OpaqueType),
from_closure: false,
span,
..
} = *best_blame.constraint()
&& (borrow_spans.for_coroutine() || borrow_spans.for_closure()) =>
{
self.report_escaping_closure_capture(
borrow_spans,
borrow_span,
region_name,
category,
span,
&format!("`{name}`"),
"function",
),
)
}
(
name,
BorrowExplanation::MustBeValidFor {
category: ConstraintCategory::Assignment,
from_closure: false,
region_name:
RegionName {
source: RegionNameSource::AnonRegionFromUpvar(upvar_span, upvar_name),
..
},
span,
ref best_blame,
..
},
) => self.report_escaping_data(borrow_span, &name, upvar_span, upvar_name, span),
) if let OutlivesConstraint {
category: ConstraintCategory::Assignment,
from_closure: false,
span,
..
} = *best_blame.constraint() =>
{
self.report_escaping_data(borrow_span, &name, upvar_span, upvar_name, span)
}
(Some(name), explanation) => self.report_local_value_does_not_live_long_enough(
location,
&name,
Expand Down Expand Up @@ -3143,13 +3152,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
explanation: BorrowExplanation<'tcx>,
) -> Diag<'infcx> {
let borrow_span = borrow_spans.var_or_use_path_span();
if let BorrowExplanation::MustBeValidFor {
category,
span,
ref opt_place_desc,
from_closure: false,
..
} = explanation
if let BorrowExplanation::MustBeValidFor { opt_place_desc, best_blame, .. } = &explanation
&& let OutlivesConstraint { category, span, from_closure: false, .. } =
*best_blame.constraint()
&& let Err(diag) = self.try_report_cannot_return_reference_to_local(
borrow,
borrow_span,
Expand Down Expand Up @@ -3356,8 +3361,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
proper_span: Span,
explanation: BorrowExplanation<'tcx>,
) -> Diag<'infcx> {
if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } =
explanation
if let BorrowExplanation::MustBeValidFor { ref best_blame, .. } = explanation
&& let OutlivesConstraint { category, span, from_closure: false, .. } =
*best_blame.constraint()
{
if let Err(diag) = self.try_report_cannot_return_reference_to_local(
borrow,
Expand Down
52 changes: 16 additions & 36 deletions compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ use rustc_middle::mir::{
Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind,
};
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::{DesugaringKind, Span, kw, sym};
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
use tracing::{debug, instrument};

use super::{RegionName, UseSpans, find_use};
use crate::borrow_set::BorrowData;
use crate::constraints::OutlivesConstraint;
use crate::consumers::OutlivesConstraint;
use crate::nll::ConstraintDescription;
use crate::region_infer::{BlameConstraint, Cause};
use crate::region_infer::{BestBlame, Cause};
use crate::{MirBorrowckCtxt, WriteKind};

#[derive(Debug)]
Expand All @@ -35,12 +35,9 @@ pub(crate) enum BorrowExplanation<'tcx> {
should_note_order: bool,
},
MustBeValidFor {
category: ConstraintCategory<'tcx>,
from_closure: bool,
span: Span,
best_blame: BestBlame<'tcx>,
region_name: RegionName,
opt_place_desc: Option<String>,
path: Vec<OutlivesConstraint<'tcx>>,
},
Unexplained,
}
Expand Down Expand Up @@ -376,13 +373,13 @@ impl<'tcx> BorrowExplanation<'tcx> {
}
}
BorrowExplanation::MustBeValidFor {
category,
span,
ref region_name,
ref opt_place_desc,
from_closure: _,
ref path,
ref best_blame,
} => {
let OutlivesConstraint { category, span, .. } = *best_blame.constraint();
let path = best_blame.path();

region_name.highlight_region_name(err);

if let Some(desc) = opt_place_desc {
Expand Down Expand Up @@ -574,24 +571,6 @@ fn suggest_rewrite_if_let<G: EmissionGuarantee>(
}

impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
fn free_region_constraint_info(
&self,
borrow_region: RegionVid,
outlived_region: RegionVid,
) -> (ConstraintCategory<'tcx>, bool, Span, Option<RegionName>, Vec<OutlivesConstraint<'tcx>>)
{
let (blame_constraint, path) = self.regioncx.best_blame_constraint(
borrow_region,
NllRegionVariableOrigin::FreeRegion,
outlived_region,
);
let BlameConstraint { category, from_closure, cause, .. } = blame_constraint;

let outlived_fr_name = self.give_region_a_name(outlived_region);

(category, from_closure, cause.span, outlived_fr_name, path)
}

/// Returns structured explanation for *why* the borrow contains the
/// point from `location`. This is key for the "3-point errors"
/// [described in the NLL RFC][d].
Expand Down Expand Up @@ -707,17 +686,18 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
// Here, under NLL: no cause was found. Under polonius: no cause was found, or a
// boring local was found, which we ignore like NLLs do to match its diagnostics.
if let Some(region) = self.regioncx.to_error_region_vid(borrow_region_vid) {
let (category, from_closure, span, region_name, path) =
self.free_region_constraint_info(borrow_region_vid, region);
if let Some(region_name) = region_name {
let best_blame = self.regioncx.best_blame_constraint(
borrow_region_vid,
NllRegionVariableOrigin::FreeRegion,
region,
);

if let Some(region_name) = self.give_region_a_name(region) {
let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref());
BorrowExplanation::MustBeValidFor {
category,
from_closure,
span,
region_name,
opt_place_desc,
path,
best_blame,
}
} else {
debug!("Could not generate a region name");
Expand Down
27 changes: 13 additions & 14 deletions compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ use rustc_trait_selection::traits::{Obligation, ObligationCtxt};
use tracing::{debug, instrument, trace};

use super::{LIMITATION_NOTE, OutlivesSuggestionBuilder, RegionName, RegionNameSource};
use crate::consumers::RegionInferenceContext;
use crate::consumers::{OutlivesConstraint, RegionInferenceContext};
use crate::nll::ConstraintDescription;
use crate::region_infer::{BlameConstraint, TypeTest};
use crate::region_infer::TypeTest;
use crate::session_diagnostics::{
FnMutError, FnMutReturnTypeErr, GenericDoesNotLiveLongEnough, LifetimeOutliveErr,
LifetimeReturnCategoryErr, RequireStaticErr, VarHereDenote,
Expand Down Expand Up @@ -414,8 +414,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
};

// Find the code to blame for the fact that `longer_fr` outlives `error_fr`.
let cause =
self.regioncx.best_blame_constraint(longer_fr, origin_longer, error_vid).0.cause;
let best_blame = self.regioncx.best_blame_constraint(longer_fr, origin_longer, error_vid);
let cause = best_blame.to_obligation_cause();

// FIXME these methods should have better names, and also probably not be this generic.
// FIXME note that we *throw away* the error element here! We probably want to
Expand Down Expand Up @@ -446,19 +446,18 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
) {
debug!("report_region_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);

let (blame_constraint, path) =
self.regioncx.best_blame_constraint(fr, fr_origin, outlived_fr);
let BlameConstraint { category, cause, variance_info, .. } = blame_constraint;
let best_blame = self.regioncx.best_blame_constraint(fr, fr_origin, outlived_fr);
let OutlivesConstraint { category, span, variance_info, .. } = *best_blame.constraint();
let path = best_blame.path();

debug!("report_region_error: category={:?} {:?} {:?}", category, cause, variance_info);
debug!("report_region_error: category={:?} {:?} {:?}", category, span, variance_info);

// Check if we can use one of the "nice region errors".
if let (Some(f), Some(o)) =
(self.regioncx.to_error_region(fr), self.regioncx.to_error_region(outlived_fr))
{
let infer_err = self.infcx.err_ctxt();
let nice =
NiceRegionError::new_from_span(&infer_err, self.mir_def_id(), cause.span, o, f);
let nice = NiceRegionError::new_from_span(&infer_err, self.mir_def_id(), span, o, f);
if let Some(diag) = nice.try_report_from_nll() {
self.buffer_error(diag);
return;
Expand All @@ -475,7 +474,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
fr_is_local, outlived_fr_is_local, category
);

let errci = ErrorConstraintInfo { fr, outlived_fr, category, span: cause.span };
let errci = ErrorConstraintInfo { fr, outlived_fr, category, span };

let mut diag = match (category, fr_is_local, outlived_fr_is_local) {
(ConstraintCategory::SolverRegionConstraint(span), _, _) => {
Expand Down Expand Up @@ -563,10 +562,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
}
}

self.add_placeholder_from_predicate_note(&mut diag, &path);
self.add_sized_or_copy_bound_info(&mut diag, category, &path);
self.add_placeholder_from_predicate_note(&mut diag, path);
self.add_sized_or_copy_bound_info(&mut diag, category, path);

for constraint in &path {
for constraint in path {
if let ConstraintCategory::Cast { is_raw_ptr_dyn_type_cast: true, .. } =
constraint.category
{
Expand Down
Loading
Loading