Move ConstraintCategory to rustc::mir
Allows us to use the category of outlive requirements inside a closure when reporting free region errors caused by its closure bounds.
This commit is contained in:
parent
ac841e7450
commit
1160e60df9
12 changed files with 86 additions and 62 deletions
|
|
@ -550,7 +550,23 @@ impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> {
|
|||
impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> {
|
||||
subject,
|
||||
outlived_free_region,
|
||||
blame_span
|
||||
blame_span,
|
||||
category
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(enum mir::ConstraintCategory {
|
||||
Return,
|
||||
TypeAnnotation,
|
||||
Cast,
|
||||
ClosureBounds,
|
||||
CallArgument,
|
||||
CopyBound,
|
||||
SizedBound,
|
||||
Assignment,
|
||||
OpaqueType,
|
||||
Boring,
|
||||
BoringNoLocation,
|
||||
Internal,
|
||||
});
|
||||
|
||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::ClosureOutlivesSubject<'gcx> {
|
||||
|
|
|
|||
|
|
@ -2646,6 +2646,43 @@ pub struct ClosureOutlivesRequirement<'tcx> {
|
|||
pub blame_span: Span,
|
||||
}
|
||||
|
||||
/// Outlives constraints can be categorized to determine whether and why they
|
||||
/// are interesting (for error reporting). Order of variants indicates sort
|
||||
/// order of the category, thereby influencing diagnostic output.
|
||||
///
|
||||
/// See also [rustc_mir::borrow_check::nll::constraints]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
|
||||
pub enum ConstraintCategory {
|
||||
Return,
|
||||
TypeAnnotation,
|
||||
Cast,
|
||||
|
||||
/// A constraint that came from checking the body of a closure.
|
||||
///
|
||||
/// We try to get the category that the closure used when reporting this.
|
||||
ClosureBounds,
|
||||
CallArgument,
|
||||
CopyBound,
|
||||
SizedBound,
|
||||
Assignment,
|
||||
OpaqueType,
|
||||
|
||||
/// A "boring" constraint (caused by the given location) is one that
|
||||
/// the user probably doesn't want to see described in diagnostics,
|
||||
/// because it is kind of an artifact of the type system setup.
|
||||
/// Example: `x = Foo { field: y }` technically creates
|
||||
/// intermediate regions representing the "type of `Foo { field: y
|
||||
/// }`", and data flows from `y` into those variables, but they
|
||||
/// are not very interesting. The assignment into `x` on the other
|
||||
/// hand might be.
|
||||
Boring,
|
||||
// Boring and applicable everywhere.
|
||||
BoringNoLocation,
|
||||
|
||||
/// A constraint that doesn't correspond to anything the user sees.
|
||||
Internal,
|
||||
}
|
||||
|
||||
/// The subject of a ClosureOutlivesRequirement -- that is, the thing
|
||||
/// that must outlive some region.
|
||||
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@
|
|||
// except according to those terms.
|
||||
|
||||
use borrow_check::nll::type_check::Locations;
|
||||
use borrow_check::nll::constraints::{ConstraintCategory, ConstraintIndex};
|
||||
use borrow_check::nll::constraints::ConstraintIndex;
|
||||
use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
|
||||
use rustc::mir::ConstraintCategory;
|
||||
use rustc::ty::RegionVid;
|
||||
use rustc_data_structures::graph;
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::mir::ConstraintCategory;
|
||||
use rustc::ty::RegionVid;
|
||||
use rustc_data_structures::graph::scc::Sccs;
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
|
|
@ -23,42 +24,6 @@ crate struct ConstraintSet {
|
|||
constraints: IndexVec<ConstraintIndex, OutlivesConstraint>,
|
||||
}
|
||||
|
||||
/// Constraints can be categorized to determine whether and why they are
|
||||
/// interesting. Order of variants indicates sort order of the category,
|
||||
/// thereby influencing diagnostic output.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||
pub enum ConstraintCategory {
|
||||
Return,
|
||||
TypeAnnotation,
|
||||
Cast,
|
||||
CallArgument,
|
||||
|
||||
/// A constraint that came from checking the body of a closure.
|
||||
///
|
||||
/// Ideally we would give an explanation that points to the relevant part
|
||||
/// of the closure's body.
|
||||
ClosureBounds,
|
||||
CopyBound,
|
||||
SizedBound,
|
||||
Assignment,
|
||||
OpaqueType,
|
||||
|
||||
/// A "boring" constraint (caused by the given location) is one that
|
||||
/// the user probably doesn't want to see described in diagnostics,
|
||||
/// because it is kind of an artifact of the type system setup.
|
||||
/// Example: `x = Foo { field: y }` technically creates
|
||||
/// intermediate regions representing the "type of `Foo { field: y
|
||||
/// }`", and data flows from `y` into those variables, but they
|
||||
/// are not very interesting. The assignment into `x` on the other
|
||||
/// hand might be.
|
||||
Boring,
|
||||
// Boring and applicable everywhere.
|
||||
BoringNoLocation,
|
||||
|
||||
/// A constraint that doesn't correspond to anything the user sees.
|
||||
Internal,
|
||||
}
|
||||
|
||||
impl ConstraintSet {
|
||||
crate fn push(&mut self, constraint: OutlivesConstraint) {
|
||||
debug!(
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use borrow_check::nll::constraints::{OutlivesConstraint, ConstraintCategory};
|
||||
use borrow_check::nll::constraints::{OutlivesConstraint};
|
||||
use borrow_check::nll::region_infer::RegionInferenceContext;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::mir::{Location, Mir};
|
||||
use rustc::mir::{ConstraintCategory, Location, Mir};
|
||||
use rustc::ty::{self, RegionVid};
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use rustc_errors::{Diagnostic, DiagnosticBuilder};
|
||||
|
|
@ -28,22 +28,26 @@ mod var_name;
|
|||
|
||||
use self::region_name::RegionName;
|
||||
|
||||
impl fmt::Display for ConstraintCategory {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
trait ConstraintDescription {
|
||||
fn description(&self) -> &'static str;
|
||||
}
|
||||
|
||||
impl ConstraintDescription for ConstraintCategory {
|
||||
fn description(&self) -> &'static str {
|
||||
// Must end with a space. Allows for empty names to be provided.
|
||||
match self {
|
||||
ConstraintCategory::Assignment => write!(f, "assignment "),
|
||||
ConstraintCategory::Return => write!(f, "returning this value "),
|
||||
ConstraintCategory::Cast => write!(f, "cast "),
|
||||
ConstraintCategory::CallArgument => write!(f, "argument "),
|
||||
ConstraintCategory::TypeAnnotation => write!(f, "type annotation "),
|
||||
ConstraintCategory::ClosureBounds => write!(f, "closure body "),
|
||||
ConstraintCategory::SizedBound => write!(f, "proving this value is `Sized` "),
|
||||
ConstraintCategory::CopyBound => write!(f, "copying this value "),
|
||||
ConstraintCategory::OpaqueType => write!(f, "opaque type "),
|
||||
ConstraintCategory::Assignment => "assignment ",
|
||||
ConstraintCategory::Return => "returning this value ",
|
||||
ConstraintCategory::Cast => "cast ",
|
||||
ConstraintCategory::CallArgument => "argument ",
|
||||
ConstraintCategory::TypeAnnotation => "type annotation ",
|
||||
ConstraintCategory::ClosureBounds => "closure body ",
|
||||
ConstraintCategory::SizedBound => "proving this value is `Sized` ",
|
||||
ConstraintCategory::CopyBound => "copying this value ",
|
||||
ConstraintCategory::OpaqueType => "opaque type ",
|
||||
ConstraintCategory::Boring
|
||||
| ConstraintCategory::BoringNoLocation
|
||||
| ConstraintCategory::Internal => write!(f, ""),
|
||||
| ConstraintCategory::Internal => "",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -358,7 +362,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
_ => {
|
||||
diag.span_label(span, format!(
|
||||
"{}requires that `{}` must outlive `{}`",
|
||||
category, fr_name, outlived_fr_name,
|
||||
category.description(), fr_name, outlived_fr_name,
|
||||
));
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ use rustc::infer::canonical::QueryRegionConstraint;
|
|||
use rustc::infer::region_constraints::{GenericKind, VarInfos, VerifyBound};
|
||||
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin, RegionVariableOrigin};
|
||||
use rustc::mir::{
|
||||
ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, Local, Location,
|
||||
Mir,
|
||||
ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements,
|
||||
ConstraintCategory, Local, Location, Mir,
|
||||
};
|
||||
use rustc::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc::util::common;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use borrow_check::nll::constraints::{ConstraintCategory, ConstraintSet, OutlivesConstraint};
|
||||
use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
|
||||
use borrow_check::nll::region_infer::TypeTest;
|
||||
use borrow_check::nll::type_check::Locations;
|
||||
use borrow_check::nll::universal_regions::UniversalRegions;
|
||||
|
|
@ -17,6 +17,7 @@ use rustc::infer::outlives::env::RegionBoundPairs;
|
|||
use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
|
||||
use rustc::infer::region_constraints::{GenericKind, VerifyBound};
|
||||
use rustc::infer::{self, SubregionOrigin};
|
||||
use rustc::mir::ConstraintCategory;
|
||||
use rustc::ty::subst::UnpackedKind;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ use borrow_check::nll::type_check::constraint_conversion;
|
|||
use borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints};
|
||||
use borrow_check::nll::universal_regions::UniversalRegions;
|
||||
use borrow_check::nll::ToRegionVid;
|
||||
use borrow_check::nll::constraints::ConstraintCategory;
|
||||
use rustc::infer::canonical::QueryRegionConstraint;
|
||||
use rustc::infer::outlives::free_region_map::FreeRegionRelations;
|
||||
use rustc::infer::region_constraints::GenericKind;
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::mir::ConstraintCategory;
|
||||
use rustc::traits::query::outlives_bounds::{self, OutlivesBound};
|
||||
use rustc::traits::query::type_op::{self, TypeOp};
|
||||
use rustc::ty::{self, RegionVid, Ty};
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ use rustc::ty::Ty;
|
|||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use super::{ConstraintCategory, Locations, TypeChecker};
|
||||
use super::{Locations, TypeChecker};
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
pub(super) fn equate_inputs_and_outputs(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
use borrow_check::location::LocationTable;
|
||||
use borrow_check::nll::constraints::ConstraintCategory;
|
||||
use borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements};
|
||||
use borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap};
|
||||
use borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap;
|
||||
|
|
@ -19,7 +18,7 @@ use dataflow::move_paths::indexes::MovePathIndex;
|
|||
use dataflow::move_paths::MoveData;
|
||||
use dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces};
|
||||
use rustc::infer::canonical::QueryRegionConstraint;
|
||||
use rustc::mir::{BasicBlock, Local, Location, Mir};
|
||||
use rustc::mir::{BasicBlock, ConstraintCategory, Local, Location, Mir};
|
||||
use rustc::traits::query::dropck_outlives::DropckOutlivesResult;
|
||||
use rustc::traits::query::type_op::outlives::DropckOutlives;
|
||||
use rustc::traits::query::type_op::TypeOp;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
use borrow_check::borrow_set::BorrowSet;
|
||||
use borrow_check::location::LocationTable;
|
||||
use borrow_check::nll::constraints::{ConstraintCategory, ConstraintSet, OutlivesConstraint};
|
||||
use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
|
||||
use borrow_check::nll::facts::AllFacts;
|
||||
use borrow_check::nll::region_infer::values::LivenessValues;
|
||||
use borrow_check::nll::region_infer::values::PlaceholderIndices;
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use borrow_check::nll::constraints::{ConstraintCategory, OutlivesConstraint};
|
||||
use borrow_check::nll::constraints::OutlivesConstraint;
|
||||
use borrow_check::nll::type_check::{BorrowCheckContext, Locations};
|
||||
use rustc::infer::canonical::{Canonical, CanonicalVarInfos};
|
||||
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
|
||||
use rustc::mir::ConstraintCategory;
|
||||
use rustc::traits::query::Fallible;
|
||||
use rustc::ty::fold::{TypeFoldable, TypeVisitor};
|
||||
use rustc::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue