Auto merge of #66815 - mark-i-m:simplify-borrow_check-errors, r=Dylan-DPC
Reorganize borrow check diagnostic code
Currently borrow checker diagnostics are split across many different modules in different places in the `librustc_mir` crate. This moves them all to a `diagnostics` module. This also reduces the nesting of the modules a bit (sooo much nesting).
I am also thinking of moving stuff out of the `nll` module since we only have one borrow checker now (🎉), and maybe it even makes sense to split out all of this stuff to a `librustc_borrow_check`, but those are for the future. Feel free to ping me here or on zulip and let me know what you think...
cc @nikomatsakis @matthewjasper @eddyb
This commit is contained in:
commit
a0312c156d
|
@ -14,18 +14,22 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use syntax::source_map::DesugaringKind;
|
use syntax::source_map::DesugaringKind;
|
||||||
|
|
||||||
use super::nll::explain_borrow::BorrowExplanation;
|
|
||||||
use super::nll::region_infer::{RegionName, RegionNameSource};
|
|
||||||
use super::prefixes::IsPrefixOf;
|
|
||||||
use super::WriteKind;
|
|
||||||
use super::borrow_set::BorrowData;
|
|
||||||
use super::MirBorrowckCtxt;
|
|
||||||
use super::{InitializationRequiringAction, PrefixSet};
|
|
||||||
use super::error_reporting::{IncludingDowncast, UseSpans};
|
|
||||||
use crate::dataflow::drop_flag_effects;
|
use crate::dataflow::drop_flag_effects;
|
||||||
use crate::dataflow::indexes::{MovePathIndex, MoveOutIndex};
|
use crate::dataflow::indexes::{MovePathIndex, MoveOutIndex};
|
||||||
use crate::util::borrowck_errors;
|
use crate::util::borrowck_errors;
|
||||||
|
|
||||||
|
use crate::borrow_check::{
|
||||||
|
prefixes::IsPrefixOf,
|
||||||
|
WriteKind,
|
||||||
|
borrow_set::BorrowData,
|
||||||
|
MirBorrowckCtxt, InitializationRequiringAction, PrefixSet
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
IncludingDowncast, UseSpans, RegionName, RegionNameSource,
|
||||||
|
explain_borrow::BorrowExplanation,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct MoveSite {
|
struct MoveSite {
|
||||||
/// Index of the "move out" that we found. The `MoveData` can
|
/// Index of the "move out" that we found. The `MoveData` can
|
||||||
|
@ -46,7 +50,7 @@ enum StorageDeadOrDrop<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
pub(super) fn report_use_of_moved_or_uninitialized(
|
pub(in crate::borrow_check) fn report_use_of_moved_or_uninitialized(
|
||||||
&mut self,
|
&mut self,
|
||||||
location: Location,
|
location: Location,
|
||||||
desired_action: InitializationRequiringAction,
|
desired_action: InitializationRequiringAction,
|
||||||
|
@ -269,7 +273,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn report_move_out_while_borrowed(
|
pub(in crate::borrow_check) fn report_move_out_while_borrowed(
|
||||||
&mut self,
|
&mut self,
|
||||||
location: Location,
|
location: Location,
|
||||||
(place, span): (&Place<'tcx>, Span),
|
(place, span): (&Place<'tcx>, Span),
|
||||||
|
@ -326,7 +330,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
err.buffer(&mut self.errors_buffer);
|
err.buffer(&mut self.errors_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn report_use_while_mutably_borrowed(
|
pub(in crate::borrow_check) fn report_use_while_mutably_borrowed(
|
||||||
&mut self,
|
&mut self,
|
||||||
location: Location,
|
location: Location,
|
||||||
(place, _span): (&Place<'tcx>, Span),
|
(place, _span): (&Place<'tcx>, Span),
|
||||||
|
@ -368,7 +372,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn report_conflicting_borrow(
|
pub(in crate::borrow_check) fn report_conflicting_borrow(
|
||||||
&mut self,
|
&mut self,
|
||||||
location: Location,
|
location: Location,
|
||||||
(place, span): (&Place<'tcx>, Span),
|
(place, span): (&Place<'tcx>, Span),
|
||||||
|
@ -614,7 +618,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
///
|
///
|
||||||
/// > cannot borrow `a.u` (via `a.u.z.c`) as immutable because it is also borrowed as
|
/// > cannot borrow `a.u` (via `a.u.z.c`) as immutable because it is also borrowed as
|
||||||
/// > mutable (via `a.u.s.b`) [E0502]
|
/// > mutable (via `a.u.s.b`) [E0502]
|
||||||
pub(super) fn describe_place_for_conflicting_borrow(
|
pub(in crate::borrow_check) fn describe_place_for_conflicting_borrow(
|
||||||
&self,
|
&self,
|
||||||
first_borrowed_place: &Place<'tcx>,
|
first_borrowed_place: &Place<'tcx>,
|
||||||
second_borrowed_place: &Place<'tcx>,
|
second_borrowed_place: &Place<'tcx>,
|
||||||
|
@ -722,7 +726,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
/// short a lifetime. (But sometimes it is more useful to report
|
/// short a lifetime. (But sometimes it is more useful to report
|
||||||
/// it as a more direct conflict between the execution of a
|
/// it as a more direct conflict between the execution of a
|
||||||
/// `Drop::drop` with an aliasing borrow.)
|
/// `Drop::drop` with an aliasing borrow.)
|
||||||
pub(super) fn report_borrowed_value_does_not_live_long_enough(
|
pub(in crate::borrow_check) fn report_borrowed_value_does_not_live_long_enough(
|
||||||
&mut self,
|
&mut self,
|
||||||
location: Location,
|
location: Location,
|
||||||
borrow: &BorrowData<'tcx>,
|
borrow: &BorrowData<'tcx>,
|
||||||
|
@ -1478,7 +1482,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn report_illegal_mutation_of_borrowed(
|
pub(in crate::borrow_check) fn report_illegal_mutation_of_borrowed(
|
||||||
&mut self,
|
&mut self,
|
||||||
location: Location,
|
location: Location,
|
||||||
(place, span): (&Place<'tcx>, Span),
|
(place, span): (&Place<'tcx>, Span),
|
||||||
|
@ -1537,7 +1541,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
/// assigned; `err_place` is a place providing a reason why
|
/// assigned; `err_place` is a place providing a reason why
|
||||||
/// `place` is not mutable (e.g., the non-`mut` local `x` in an
|
/// `place` is not mutable (e.g., the non-`mut` local `x` in an
|
||||||
/// assignment to `x.f`).
|
/// assignment to `x.f`).
|
||||||
pub(super) fn report_illegal_reassignment(
|
pub(in crate::borrow_check) fn report_illegal_reassignment(
|
||||||
&mut self,
|
&mut self,
|
||||||
_location: Location,
|
_location: Location,
|
||||||
(place, span): (&Place<'tcx>, Span),
|
(place, span): (&Place<'tcx>, Span),
|
||||||
|
@ -2080,7 +2084,7 @@ enum AnnotatedBorrowFnSignature<'tcx> {
|
||||||
impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
|
impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
|
||||||
/// Annotate the provided diagnostic with information about borrow from the fn signature that
|
/// Annotate the provided diagnostic with information about borrow from the fn signature that
|
||||||
/// helps explain.
|
/// helps explain.
|
||||||
pub(super) fn emit(
|
pub(in crate::borrow_check) fn emit(
|
||||||
&self,
|
&self,
|
||||||
cx: &mut MirBorrowckCtxt<'_, 'tcx>,
|
cx: &mut MirBorrowckCtxt<'_, 'tcx>,
|
||||||
diag: &mut DiagnosticBuilder<'_>,
|
diag: &mut DiagnosticBuilder<'_>,
|
|
@ -1,8 +1,7 @@
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use crate::borrow_check::borrow_set::BorrowData;
|
use crate::borrow_check::borrow_set::BorrowData;
|
||||||
use crate::borrow_check::error_reporting::UseSpans;
|
use crate::borrow_check::nll::region_infer::Cause;
|
||||||
use crate::borrow_check::nll::region_infer::{Cause, RegionName};
|
|
||||||
use crate::borrow_check::nll::ConstraintDescription;
|
use crate::borrow_check::nll::ConstraintDescription;
|
||||||
use crate::borrow_check::{MirBorrowckCtxt, WriteKind};
|
use crate::borrow_check::{MirBorrowckCtxt, WriteKind};
|
||||||
use rustc::mir::{
|
use rustc::mir::{
|
||||||
|
@ -17,7 +16,7 @@ use rustc_errors::DiagnosticBuilder;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use syntax_pos::symbol::Symbol;
|
use syntax_pos::symbol::Symbol;
|
||||||
|
|
||||||
mod find_use;
|
use super::{UseSpans, find_use, RegionName};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(in crate::borrow_check) enum BorrowExplanation {
|
pub(in crate::borrow_check) enum BorrowExplanation {
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! Borrow checker diagnostics.
|
||||||
|
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::def::Namespace;
|
use rustc::hir::def::Namespace;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
|
@ -17,6 +19,22 @@ use super::borrow_set::BorrowData;
|
||||||
use super::MirBorrowckCtxt;
|
use super::MirBorrowckCtxt;
|
||||||
use crate::dataflow::move_paths::{InitLocation, LookupResult};
|
use crate::dataflow::move_paths::{InitLocation, LookupResult};
|
||||||
|
|
||||||
|
mod find_use;
|
||||||
|
mod var_name;
|
||||||
|
mod region_name;
|
||||||
|
mod outlives_suggestion;
|
||||||
|
|
||||||
|
mod conflict_errors;
|
||||||
|
mod move_errors;
|
||||||
|
mod mutability_errors;
|
||||||
|
mod region_errors;
|
||||||
|
mod explain_borrow;
|
||||||
|
|
||||||
|
crate use mutability_errors::AccessKind;
|
||||||
|
crate use region_name::{RegionName, RegionNameSource, RegionErrorNamingCtx};
|
||||||
|
crate use region_errors::{ErrorReportingCtx, ErrorConstraintInfo};
|
||||||
|
crate use outlives_suggestion::OutlivesSuggestionBuilder;
|
||||||
|
|
||||||
pub(super) struct IncludingDowncast(pub(super) bool);
|
pub(super) struct IncludingDowncast(pub(super) bool);
|
||||||
|
|
||||||
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|
@ -5,7 +5,7 @@ use syntax_pos::Span;
|
||||||
|
|
||||||
use crate::borrow_check::MirBorrowckCtxt;
|
use crate::borrow_check::MirBorrowckCtxt;
|
||||||
use crate::borrow_check::prefixes::PrefixSet;
|
use crate::borrow_check::prefixes::PrefixSet;
|
||||||
use crate::borrow_check::error_reporting::UseSpans;
|
use crate::borrow_check::diagnostics::UseSpans;
|
||||||
use crate::dataflow::move_paths::{
|
use crate::dataflow::move_paths::{
|
||||||
IllegalMoveOrigin, IllegalMoveOriginKind,
|
IllegalMoveOrigin, IllegalMoveOriginKind,
|
||||||
LookupResult, MoveError, MovePathIndex,
|
LookupResult, MoveError, MovePathIndex,
|
|
@ -8,18 +8,18 @@ use syntax_pos::Span;
|
||||||
use syntax_pos::symbol::kw;
|
use syntax_pos::symbol::kw;
|
||||||
|
|
||||||
use crate::borrow_check::MirBorrowckCtxt;
|
use crate::borrow_check::MirBorrowckCtxt;
|
||||||
use crate::borrow_check::error_reporting::BorrowedContentSource;
|
use crate::borrow_check::diagnostics::BorrowedContentSource;
|
||||||
use crate::util::collect_writes::FindAssignments;
|
use crate::util::collect_writes::FindAssignments;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub(super) enum AccessKind {
|
pub(crate) enum AccessKind {
|
||||||
MutableBorrow,
|
MutableBorrow,
|
||||||
Mutate,
|
Mutate,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
pub(super) fn report_mutability_error(
|
pub(crate) fn report_mutability_error(
|
||||||
&mut self,
|
&mut self,
|
||||||
access_place: &Place<'tcx>,
|
access_place: &Place<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
|
@ -13,12 +13,10 @@ use syntax_pos::symbol::Symbol;
|
||||||
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::borrow_check::nll::region_infer::{
|
use crate::borrow_check::nll::region_infer::RegionInferenceContext;
|
||||||
error_reporting::{
|
|
||||||
region_name::{RegionName, RegionNameSource},
|
use super::{
|
||||||
ErrorConstraintInfo, ErrorReportingCtx, RegionErrorNamingCtx,
|
RegionName, RegionNameSource, ErrorConstraintInfo, ErrorReportingCtx, RegionErrorNamingCtx,
|
||||||
},
|
|
||||||
RegionInferenceContext,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The different things we could suggest.
|
/// The different things we could suggest.
|
|
@ -19,14 +19,7 @@ use syntax::symbol::kw;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use syntax_pos::symbol::Symbol;
|
use syntax_pos::symbol::Symbol;
|
||||||
|
|
||||||
use self::outlives_suggestion::OutlivesSuggestionBuilder;
|
use super::{OutlivesSuggestionBuilder, RegionName, RegionNameSource, RegionErrorNamingCtx};
|
||||||
|
|
||||||
pub mod outlives_suggestion;
|
|
||||||
|
|
||||||
mod region_name;
|
|
||||||
mod var_name;
|
|
||||||
|
|
||||||
crate use self::region_name::{RegionName, RegionNameSource, RegionErrorNamingCtx};
|
|
||||||
|
|
||||||
impl ConstraintDescription for ConstraintCategory {
|
impl ConstraintDescription for ConstraintCategory {
|
||||||
fn description(&self) -> &'static str {
|
fn description(&self) -> &'static str {
|
||||||
|
@ -61,36 +54,36 @@ enum Trace {
|
||||||
/// Various pieces of state used when reporting borrow checker errors.
|
/// Various pieces of state used when reporting borrow checker errors.
|
||||||
pub struct ErrorReportingCtx<'a, 'b, 'tcx> {
|
pub struct ErrorReportingCtx<'a, 'b, 'tcx> {
|
||||||
/// The region inference context used for borrow chekcing this MIR body.
|
/// The region inference context used for borrow chekcing this MIR body.
|
||||||
region_infcx: &'b RegionInferenceContext<'tcx>,
|
pub(super) region_infcx: &'b RegionInferenceContext<'tcx>,
|
||||||
|
|
||||||
/// The inference context used for type checking.
|
/// The inference context used for type checking.
|
||||||
infcx: &'b InferCtxt<'a, 'tcx>,
|
pub(super) infcx: &'b InferCtxt<'a, 'tcx>,
|
||||||
|
|
||||||
/// The MIR def we are reporting errors on.
|
/// The MIR def we are reporting errors on.
|
||||||
mir_def_id: DefId,
|
pub(super) mir_def_id: DefId,
|
||||||
|
|
||||||
/// The MIR body we are reporting errors on (for convenience).
|
/// The MIR body we are reporting errors on (for convenience).
|
||||||
body: &'b Body<'tcx>,
|
pub(super) body: &'b Body<'tcx>,
|
||||||
|
|
||||||
/// User variable names for MIR locals (where applicable).
|
/// User variable names for MIR locals (where applicable).
|
||||||
local_names: &'b IndexVec<Local, Option<Symbol>>,
|
pub(super) local_names: &'b IndexVec<Local, Option<Symbol>>,
|
||||||
|
|
||||||
/// Any upvars for the MIR body we have kept track of during borrow checking.
|
/// Any upvars for the MIR body we have kept track of during borrow checking.
|
||||||
upvars: &'b [Upvar],
|
pub(super) upvars: &'b [Upvar],
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information about the various region constraints involved in a borrow checker error.
|
/// Information about the various region constraints involved in a borrow checker error.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ErrorConstraintInfo {
|
pub struct ErrorConstraintInfo {
|
||||||
// fr: outlived_fr
|
// fr: outlived_fr
|
||||||
fr: RegionVid,
|
pub(super) fr: RegionVid,
|
||||||
fr_is_local: bool,
|
pub(super) fr_is_local: bool,
|
||||||
outlived_fr: RegionVid,
|
pub(super) outlived_fr: RegionVid,
|
||||||
outlived_fr_is_local: bool,
|
pub(super) outlived_fr_is_local: bool,
|
||||||
|
|
||||||
// Category and span for best blame constraint
|
// Category and span for best blame constraint
|
||||||
category: ConstraintCategory,
|
pub(super) category: ConstraintCategory,
|
||||||
span: Span,
|
pub(super) span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> RegionInferenceContext<'tcx> {
|
impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
|
@ -368,7 +361,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`.
|
/// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`.
|
||||||
pub(super) fn report_error<'a>(
|
pub(in crate::borrow_check) fn report_error<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
local_names: &IndexVec<Local, Option<Symbol>>,
|
local_names: &IndexVec<Local, Option<Symbol>>,
|
|
@ -1,12 +1,5 @@
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
|
|
||||||
use crate::borrow_check::nll::region_infer::{
|
|
||||||
RegionInferenceContext,
|
|
||||||
error_reporting::ErrorReportingCtx,
|
|
||||||
};
|
|
||||||
use crate::borrow_check::nll::universal_regions::DefiningTy;
|
|
||||||
use crate::borrow_check::nll::ToRegionVid;
|
|
||||||
use crate::borrow_check::Upvar;
|
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::def::{Res, DefKind};
|
use rustc::hir::def::{Res, DefKind};
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
|
@ -21,6 +14,15 @@ use syntax::symbol::kw;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use syntax_pos::{Span, symbol::Symbol, DUMMY_SP};
|
use syntax_pos::{Span, symbol::Symbol, DUMMY_SP};
|
||||||
|
|
||||||
|
use crate::borrow_check::{
|
||||||
|
nll::region_infer::RegionInferenceContext,
|
||||||
|
nll::universal_regions::DefiningTy,
|
||||||
|
nll::ToRegionVid,
|
||||||
|
Upvar,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::region_errors::ErrorReportingCtx;
|
||||||
|
|
||||||
/// A name for a particular region used in emitting diagnostics. This name could be a generated
|
/// A name for a particular region used in emitting diagnostics. This name could be a generated
|
||||||
/// name like `'1`, a name used by the user like `'a`, or a name like `'static`.
|
/// name like `'1`, a name used by the user like `'a`, or a name like `'static`.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
|
@ -46,17 +46,14 @@ use self::flows::Flows;
|
||||||
use self::location::LocationTable;
|
use self::location::LocationTable;
|
||||||
use self::prefixes::PrefixSet;
|
use self::prefixes::PrefixSet;
|
||||||
use self::MutateMode::{JustWrite, WriteAndRead};
|
use self::MutateMode::{JustWrite, WriteAndRead};
|
||||||
use self::mutability_errors::AccessKind;
|
use self::diagnostics::AccessKind;
|
||||||
|
|
||||||
use self::path_utils::*;
|
use self::path_utils::*;
|
||||||
|
|
||||||
crate mod borrow_set;
|
crate mod borrow_set;
|
||||||
mod error_reporting;
|
mod diagnostics;
|
||||||
mod flows;
|
mod flows;
|
||||||
mod location;
|
mod location;
|
||||||
mod conflict_errors;
|
|
||||||
mod move_errors;
|
|
||||||
mod mutability_errors;
|
|
||||||
mod path_utils;
|
mod path_utils;
|
||||||
crate mod place_ext;
|
crate mod place_ext;
|
||||||
crate mod places_conflict;
|
crate mod places_conflict;
|
||||||
|
|
|
@ -32,17 +32,17 @@ use crate::util as mir_util;
|
||||||
use crate::util::pretty;
|
use crate::util::pretty;
|
||||||
|
|
||||||
mod constraint_generation;
|
mod constraint_generation;
|
||||||
pub mod explain_borrow;
|
|
||||||
mod facts;
|
mod facts;
|
||||||
mod invalidation;
|
mod invalidation;
|
||||||
crate mod region_infer;
|
|
||||||
mod renumber;
|
mod renumber;
|
||||||
crate mod type_check;
|
|
||||||
mod universal_regions;
|
|
||||||
|
|
||||||
mod constraints;
|
|
||||||
mod member_constraints;
|
mod member_constraints;
|
||||||
|
|
||||||
|
crate mod constraints;
|
||||||
|
crate mod universal_regions;
|
||||||
|
crate mod type_check;
|
||||||
|
crate mod region_infer;
|
||||||
|
|
||||||
use self::facts::AllFacts;
|
use self::facts::AllFacts;
|
||||||
use self::region_infer::RegionInferenceContext;
|
use self::region_infer::RegionInferenceContext;
|
||||||
use self::universal_regions::UniversalRegions;
|
use self::universal_regions::UniversalRegions;
|
||||||
|
|
|
@ -1,21 +1,5 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::borrow_check::nll::{
|
|
||||||
constraints::{
|
|
||||||
graph::NormalConstraintGraph,
|
|
||||||
ConstraintSccIndex,
|
|
||||||
OutlivesConstraint,
|
|
||||||
OutlivesConstraintSet,
|
|
||||||
},
|
|
||||||
member_constraints::{MemberConstraintSet, NllMemberConstraintIndex},
|
|
||||||
region_infer::values::{
|
|
||||||
PlaceholderIndices, RegionElement, ToElementIndex
|
|
||||||
},
|
|
||||||
region_infer::error_reporting::outlives_suggestion::OutlivesSuggestionBuilder,
|
|
||||||
type_check::{free_region_relations::UniversalRegionRelations, Locations},
|
|
||||||
};
|
|
||||||
use crate::borrow_check::Upvar;
|
|
||||||
|
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::infer::canonical::QueryOutlivesConstraint;
|
use rustc::infer::canonical::QueryOutlivesConstraint;
|
||||||
use rustc::infer::opaque_types;
|
use rustc::infer::opaque_types;
|
||||||
|
@ -38,13 +22,31 @@ use rustc_errors::{Diagnostic, DiagnosticBuilder};
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use syntax_pos::symbol::Symbol;
|
use syntax_pos::symbol::Symbol;
|
||||||
|
|
||||||
crate use self::error_reporting::{RegionName, RegionNameSource, RegionErrorNamingCtx};
|
use crate::borrow_check::{
|
||||||
|
nll::{
|
||||||
|
constraints::{
|
||||||
|
graph::NormalConstraintGraph,
|
||||||
|
ConstraintSccIndex,
|
||||||
|
OutlivesConstraint,
|
||||||
|
OutlivesConstraintSet,
|
||||||
|
},
|
||||||
|
member_constraints::{MemberConstraintSet, NllMemberConstraintIndex},
|
||||||
|
region_infer::values::{
|
||||||
|
PlaceholderIndices, RegionElement, ToElementIndex
|
||||||
|
},
|
||||||
|
type_check::{free_region_relations::UniversalRegionRelations, Locations},
|
||||||
|
},
|
||||||
|
diagnostics::{
|
||||||
|
OutlivesSuggestionBuilder, RegionErrorNamingCtx,
|
||||||
|
},
|
||||||
|
Upvar,
|
||||||
|
};
|
||||||
|
|
||||||
use self::values::{LivenessValues, RegionValueElements, RegionValues};
|
use self::values::{LivenessValues, RegionValueElements, RegionValues};
|
||||||
use super::universal_regions::UniversalRegions;
|
use super::universal_regions::UniversalRegions;
|
||||||
use super::ToRegionVid;
|
use super::ToRegionVid;
|
||||||
|
|
||||||
mod dump_mir;
|
mod dump_mir;
|
||||||
mod error_reporting;
|
|
||||||
mod graphviz;
|
mod graphviz;
|
||||||
|
|
||||||
pub mod values;
|
pub mod values;
|
||||||
|
@ -54,48 +56,51 @@ pub struct RegionInferenceContext<'tcx> {
|
||||||
/// variables are identified by their index (`RegionVid`). The
|
/// variables are identified by their index (`RegionVid`). The
|
||||||
/// definition contains information about where the region came
|
/// definition contains information about where the region came
|
||||||
/// from as well as its final inferred value.
|
/// from as well as its final inferred value.
|
||||||
definitions: IndexVec<RegionVid, RegionDefinition<'tcx>>,
|
pub(in crate::borrow_check) definitions: IndexVec<RegionVid, RegionDefinition<'tcx>>,
|
||||||
|
|
||||||
/// The liveness constraints added to each region. For most
|
/// The liveness constraints added to each region. For most
|
||||||
/// regions, these start out empty and steadily grow, though for
|
/// regions, these start out empty and steadily grow, though for
|
||||||
/// each universally quantified region R they start out containing
|
/// each universally quantified region R they start out containing
|
||||||
/// the entire CFG and `end(R)`.
|
/// the entire CFG and `end(R)`.
|
||||||
liveness_constraints: LivenessValues<RegionVid>,
|
pub(in crate::borrow_check) liveness_constraints: LivenessValues<RegionVid>,
|
||||||
|
|
||||||
/// The outlives constraints computed by the type-check.
|
/// The outlives constraints computed by the type-check.
|
||||||
constraints: Rc<OutlivesConstraintSet>,
|
pub(in crate::borrow_check) constraints: Rc<OutlivesConstraintSet>,
|
||||||
|
|
||||||
/// The constraint-set, but in graph form, making it easy to traverse
|
/// The constraint-set, but in graph form, making it easy to traverse
|
||||||
/// the constraints adjacent to a particular region. Used to construct
|
/// the constraints adjacent to a particular region. Used to construct
|
||||||
/// the SCC (see `constraint_sccs`) and for error reporting.
|
/// the SCC (see `constraint_sccs`) and for error reporting.
|
||||||
constraint_graph: Rc<NormalConstraintGraph>,
|
pub(in crate::borrow_check) constraint_graph: Rc<NormalConstraintGraph>,
|
||||||
|
|
||||||
/// The SCC computed from `constraints` and the constraint
|
/// The SCC computed from `constraints` and the constraint
|
||||||
/// graph. We have an edge from SCC A to SCC B if `A: B`. Used to
|
/// graph. We have an edge from SCC A to SCC B if `A: B`. Used to
|
||||||
/// compute the values of each region.
|
/// compute the values of each region.
|
||||||
constraint_sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
|
pub(in crate::borrow_check) constraint_sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
|
||||||
|
|
||||||
/// Reverse of the SCC constraint graph -- i.e., an edge `A -> B`
|
/// Reverse of the SCC constraint graph -- i.e., an edge `A -> B`
|
||||||
/// exists if `B: A`. Computed lazilly.
|
/// exists if `B: A`. Computed lazilly.
|
||||||
rev_constraint_graph: Option<Rc<VecGraph<ConstraintSccIndex>>>,
|
pub(in crate::borrow_check) rev_constraint_graph:
|
||||||
|
Option<Rc<VecGraph<ConstraintSccIndex>>>,
|
||||||
|
|
||||||
/// The "R0 member of [R1..Rn]" constraints, indexed by SCC.
|
/// The "R0 member of [R1..Rn]" constraints, indexed by SCC.
|
||||||
member_constraints: Rc<MemberConstraintSet<'tcx, ConstraintSccIndex>>,
|
pub(in crate::borrow_check) member_constraints:
|
||||||
|
Rc<MemberConstraintSet<'tcx, ConstraintSccIndex>>,
|
||||||
|
|
||||||
/// Records the member constraints that we applied to each scc.
|
/// Records the member constraints that we applied to each scc.
|
||||||
/// This is useful for error reporting. Once constraint
|
/// This is useful for error reporting. Once constraint
|
||||||
/// propagation is done, this vector is sorted according to
|
/// propagation is done, this vector is sorted according to
|
||||||
/// `member_region_scc`.
|
/// `member_region_scc`.
|
||||||
member_constraints_applied: Vec<AppliedMemberConstraint>,
|
pub(in crate::borrow_check) member_constraints_applied: Vec<AppliedMemberConstraint>,
|
||||||
|
|
||||||
/// Map closure bounds to a `Span` that should be used for error reporting.
|
/// Map closure bounds to a `Span` that should be used for error reporting.
|
||||||
closure_bounds_mapping:
|
pub(in crate::borrow_check) closure_bounds_mapping:
|
||||||
FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
|
FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
|
||||||
|
|
||||||
/// Contains the minimum universe of any variable within the same
|
/// Contains the minimum universe of any variable within the same
|
||||||
/// SCC. We will ensure that no SCC contains values that are not
|
/// SCC. We will ensure that no SCC contains values that are not
|
||||||
/// visible from this index.
|
/// visible from this index.
|
||||||
scc_universes: IndexVec<ConstraintSccIndex, ty::UniverseIndex>,
|
pub(in crate::borrow_check) scc_universes:
|
||||||
|
IndexVec<ConstraintSccIndex, ty::UniverseIndex>,
|
||||||
|
|
||||||
/// Contains a "representative" from each SCC. This will be the
|
/// Contains a "representative" from each SCC. This will be the
|
||||||
/// minimal RegionVid belonging to that universe. It is used as a
|
/// minimal RegionVid belonging to that universe. It is used as a
|
||||||
|
@ -104,23 +109,25 @@ pub struct RegionInferenceContext<'tcx> {
|
||||||
/// of its SCC and be sure that -- if they have the same repr --
|
/// of its SCC and be sure that -- if they have the same repr --
|
||||||
/// they *must* be equal (though not having the same repr does not
|
/// they *must* be equal (though not having the same repr does not
|
||||||
/// mean they are unequal).
|
/// mean they are unequal).
|
||||||
scc_representatives: IndexVec<ConstraintSccIndex, ty::RegionVid>,
|
pub(in crate::borrow_check) scc_representatives:
|
||||||
|
IndexVec<ConstraintSccIndex, ty::RegionVid>,
|
||||||
|
|
||||||
/// The final inferred values of the region variables; we compute
|
/// The final inferred values of the region variables; we compute
|
||||||
/// one value per SCC. To get the value for any given *region*,
|
/// one value per SCC. To get the value for any given *region*,
|
||||||
/// you first find which scc it is a part of.
|
/// you first find which scc it is a part of.
|
||||||
scc_values: RegionValues<ConstraintSccIndex>,
|
pub(in crate::borrow_check) scc_values: RegionValues<ConstraintSccIndex>,
|
||||||
|
|
||||||
/// Type constraints that we check after solving.
|
/// Type constraints that we check after solving.
|
||||||
type_tests: Vec<TypeTest<'tcx>>,
|
pub(in crate::borrow_check) type_tests: Vec<TypeTest<'tcx>>,
|
||||||
|
|
||||||
/// Information about the universally quantified regions in scope
|
/// Information about the universally quantified regions in scope
|
||||||
/// on this function.
|
/// on this function.
|
||||||
universal_regions: Rc<UniversalRegions<'tcx>>,
|
pub (in crate::borrow_check) universal_regions: Rc<UniversalRegions<'tcx>>,
|
||||||
|
|
||||||
/// Information about how the universally quantified regions in
|
/// Information about how the universally quantified regions in
|
||||||
/// scope on this function relate to one another.
|
/// scope on this function relate to one another.
|
||||||
universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
|
pub(in crate::borrow_check) universal_region_relations:
|
||||||
|
Rc<UniversalRegionRelations<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Each time that `apply_member_constraint` is successful, it appends
|
/// Each time that `apply_member_constraint` is successful, it appends
|
||||||
|
@ -132,38 +139,38 @@ pub struct RegionInferenceContext<'tcx> {
|
||||||
/// with `'R: 'O` where `'R` is the pick-region and `'O` is the
|
/// with `'R: 'O` where `'R` is the pick-region and `'O` is the
|
||||||
/// minimal viable option.
|
/// minimal viable option.
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
struct AppliedMemberConstraint {
|
pub(crate) struct AppliedMemberConstraint {
|
||||||
/// The SCC that was affected. (The "member region".)
|
/// The SCC that was affected. (The "member region".)
|
||||||
///
|
///
|
||||||
/// The vector if `AppliedMemberConstraint` elements is kept sorted
|
/// The vector if `AppliedMemberConstraint` elements is kept sorted
|
||||||
/// by this field.
|
/// by this field.
|
||||||
member_region_scc: ConstraintSccIndex,
|
pub(in crate::borrow_check) member_region_scc: ConstraintSccIndex,
|
||||||
|
|
||||||
/// The "best option" that `apply_member_constraint` found -- this was
|
/// The "best option" that `apply_member_constraint` found -- this was
|
||||||
/// added as an "ad-hoc" lower-bound to `member_region_scc`.
|
/// added as an "ad-hoc" lower-bound to `member_region_scc`.
|
||||||
min_choice: ty::RegionVid,
|
pub(in crate::borrow_check) min_choice: ty::RegionVid,
|
||||||
|
|
||||||
/// The "member constraint index" -- we can find out details about
|
/// The "member constraint index" -- we can find out details about
|
||||||
/// the constraint from
|
/// the constraint from
|
||||||
/// `set.member_constraints[member_constraint_index]`.
|
/// `set.member_constraints[member_constraint_index]`.
|
||||||
member_constraint_index: NllMemberConstraintIndex,
|
pub(in crate::borrow_check) member_constraint_index: NllMemberConstraintIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RegionDefinition<'tcx> {
|
pub(crate) struct RegionDefinition<'tcx> {
|
||||||
/// What kind of variable is this -- a free region? existential
|
/// What kind of variable is this -- a free region? existential
|
||||||
/// variable? etc. (See the `NLLRegionVariableOrigin` for more
|
/// variable? etc. (See the `NLLRegionVariableOrigin` for more
|
||||||
/// info.)
|
/// info.)
|
||||||
origin: NLLRegionVariableOrigin,
|
pub(in crate::borrow_check) origin: NLLRegionVariableOrigin,
|
||||||
|
|
||||||
/// Which universe is this region variable defined in? This is
|
/// Which universe is this region variable defined in? This is
|
||||||
/// most often `ty::UniverseIndex::ROOT`, but when we encounter
|
/// most often `ty::UniverseIndex::ROOT`, but when we encounter
|
||||||
/// forall-quantifiers like `for<'a> { 'a = 'b }`, we would create
|
/// forall-quantifiers like `for<'a> { 'a = 'b }`, we would create
|
||||||
/// the variable for `'a` in a fresh universe that extends ROOT.
|
/// the variable for `'a` in a fresh universe that extends ROOT.
|
||||||
universe: ty::UniverseIndex,
|
pub(in crate::borrow_check) universe: ty::UniverseIndex,
|
||||||
|
|
||||||
/// If this is 'static or an early-bound region, then this is
|
/// If this is 'static or an early-bound region, then this is
|
||||||
/// `Some(X)` where `X` is the name of the region.
|
/// `Some(X)` where `X` is the name of the region.
|
||||||
external_name: Option<ty::Region<'tcx>>,
|
pub(in crate::borrow_check) external_name: Option<ty::Region<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// N.B., the variants in `Cause` are intentionally ordered. Lower
|
/// N.B., the variants in `Cause` are intentionally ordered. Lower
|
||||||
|
@ -455,7 +462,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
/// Once region solving has completed, this function will return
|
/// Once region solving has completed, this function will return
|
||||||
/// the member constraints that were applied to the value of a given
|
/// the member constraints that were applied to the value of a given
|
||||||
/// region `r`. See `AppliedMemberConstraint`.
|
/// region `r`. See `AppliedMemberConstraint`.
|
||||||
fn applied_member_constraints(&self, r: impl ToRegionVid) -> &[AppliedMemberConstraint] {
|
pub(in crate::borrow_check) fn applied_member_constraints(
|
||||||
|
&self, r: impl ToRegionVid
|
||||||
|
) -> &[AppliedMemberConstraint] {
|
||||||
let scc = self.constraint_sccs.scc(r.to_region_vid());
|
let scc = self.constraint_sccs.scc(r.to_region_vid());
|
||||||
binary_search_util::binary_search_slice(
|
binary_search_util::binary_search_slice(
|
||||||
&self.member_constraints_applied,
|
&self.member_constraints_applied,
|
||||||
|
|
Loading…
Reference in New Issue