diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 656f5795e18b..f69d1d159005 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -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> for mir::ClosureOutlivesSubject<'gcx> { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index aec6bb7c3c1f..61e8ad4a8c48 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -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)] diff --git a/src/librustc_mir/borrow_check/nll/constraints/graph.rs b/src/librustc_mir/borrow_check/nll/constraints/graph.rs index 2e018f746f38..3d4b2456f965 100644 --- a/src/librustc_mir/borrow_check/nll/constraints/graph.rs +++ b/src/librustc_mir/borrow_check/nll/constraints/graph.rs @@ -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; diff --git a/src/librustc_mir/borrow_check/nll/constraints/mod.rs b/src/librustc_mir/borrow_check/nll/constraints/mod.rs index 76ebc06bfd2f..a873af8333a7 100644 --- a/src/librustc_mir/borrow_check/nll/constraints/mod.rs +++ b/src/librustc_mir/borrow_check/nll/constraints/mod.rs @@ -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, } -/// 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!( diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 31d7c7c631e1..9acfe42e6ca6 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -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, )); }, } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 4a8f011b606b..a6730fa847f5 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -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; diff --git a/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs index dabf669eca65..4ab0f952bdee 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs @@ -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; diff --git a/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs index f33909db78f9..35342b2129e6 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs @@ -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}; diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs index 942f19965bf3..a4665984d3e0 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs @@ -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( diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs index 6c1252fc73d8..bc4e0ca23513 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs @@ -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; diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 99ac80862b13..553d4a426a76 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -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; diff --git a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs index 4e8dbf8498e2..41aab02d1e82 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs @@ -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};