mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +00:00
convert from an UnlessNll
flag to a SuppressRegionErrors
flag
Hopefully this will help clarify the behavior in the various borrowck modes
This commit is contained in:
parent
0b4791e60b
commit
a13c9f6bfd
@ -55,7 +55,7 @@
|
|||||||
//! ported to this system, and which relies on string concatenation at the
|
//! ported to this system, and which relies on string concatenation at the
|
||||||
//! time of error detection.
|
//! time of error detection.
|
||||||
|
|
||||||
use infer::{self, UnlessNll};
|
use infer::{self, SuppressRegionErrors};
|
||||||
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
|
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
|
||||||
use super::region_constraints::GenericKind;
|
use super::region_constraints::GenericKind;
|
||||||
use super::lexical_region_resolve::RegionResolutionError;
|
use super::lexical_region_resolve::RegionResolutionError;
|
||||||
@ -68,7 +68,6 @@ use middle::region;
|
|||||||
use traits::{ObligationCause, ObligationCauseCode};
|
use traits::{ObligationCause, ObligationCauseCode};
|
||||||
use ty::{self, subst::Subst, Region, Ty, TyCtxt, TypeFoldable, TyKind};
|
use ty::{self, subst::Subst, Region, Ty, TyCtxt, TypeFoldable, TyKind};
|
||||||
use ty::error::TypeError;
|
use ty::error::TypeError;
|
||||||
use session::config::BorrowckMode;
|
|
||||||
use syntax::ast::DUMMY_NODE_ID;
|
use syntax::ast::DUMMY_NODE_ID;
|
||||||
use syntax_pos::{Pos, Span};
|
use syntax_pos::{Pos, Span};
|
||||||
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
|
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
|
||||||
@ -298,20 +297,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
&self,
|
&self,
|
||||||
region_scope_tree: ®ion::ScopeTree,
|
region_scope_tree: ®ion::ScopeTree,
|
||||||
errors: &Vec<RegionResolutionError<'tcx>>,
|
errors: &Vec<RegionResolutionError<'tcx>>,
|
||||||
unless_nll: UnlessNll,
|
suppress: SuppressRegionErrors,
|
||||||
) {
|
) {
|
||||||
debug!("report_region_errors(): {} errors to start", errors.len());
|
debug!("report_region_errors(): {} errors to start, suppress = {:?}", errors.len(), suppress);
|
||||||
|
|
||||||
// If the errors will later be reported by NLL, choose wether to display them or not based
|
if suppress.suppressed() {
|
||||||
// on the borrowck mode
|
return;
|
||||||
if unless_nll.0 {
|
|
||||||
match self.tcx.borrowck_mode() {
|
|
||||||
// If we're on AST or Migrate mode, report AST region errors
|
|
||||||
BorrowckMode::Ast | BorrowckMode::Migrate => {},
|
|
||||||
// If we're on MIR or Compare mode, don't report AST region errors as they should
|
|
||||||
// be reported by NLL
|
|
||||||
BorrowckMode::Compare | BorrowckMode::Mir => return,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to pre-process the errors, which will group some of them
|
// try to pre-process the errors, which will group some of them
|
||||||
|
@ -24,6 +24,7 @@ use middle::free_region::RegionRelations;
|
|||||||
use middle::lang_items;
|
use middle::lang_items;
|
||||||
use middle::region;
|
use middle::region;
|
||||||
use rustc_data_structures::unify as ut;
|
use rustc_data_structures::unify as ut;
|
||||||
|
use session::config::BorrowckMode;
|
||||||
use std::cell::{Cell, Ref, RefCell, RefMut};
|
use std::cell::{Cell, Ref, RefCell, RefMut};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -80,15 +81,37 @@ pub type Bound<T> = Option<T>;
|
|||||||
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
|
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
|
||||||
pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
|
pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
|
||||||
|
|
||||||
/// A flag that is given when running region resolution: if true, it
|
/// A flag that is used to suppress region errors. This is normally
|
||||||
/// indicates that we should not report the region errors to the user
|
/// false, but sometimes -- when we are doing region checks that the
|
||||||
/// if NLL is enabled, since NLL will also detect them (and do a
|
/// NLL borrow checker will also do -- it might be set to true.
|
||||||
/// better job of it).
|
#[derive(Copy, Clone, Default, Debug)]
|
||||||
///
|
pub struct SuppressRegionErrors {
|
||||||
/// Currently, NLL only runs on HIR bodies, so you should use `false`
|
suppressed: bool
|
||||||
/// unless you are region-checking a `hir::Body` (basically, a fn or
|
}
|
||||||
/// expression).
|
|
||||||
pub struct UnlessNll(pub bool);
|
impl SuppressRegionErrors {
|
||||||
|
pub fn suppressed(self) -> bool {
|
||||||
|
self.suppressed
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Indicates that the MIR borrowck will repeat these region
|
||||||
|
/// checks, so we should ignore errors if NLL is (unconditionally)
|
||||||
|
/// enabled.
|
||||||
|
pub fn when_nll_is_enabled(tcx: TyCtxt<'_, '_, '_>) -> Self {
|
||||||
|
match tcx.borrowck_mode() {
|
||||||
|
// If we're on AST or Migrate mode, report AST region errors
|
||||||
|
BorrowckMode::Ast | BorrowckMode::Migrate => SuppressRegionErrors {
|
||||||
|
suppressed: false
|
||||||
|
},
|
||||||
|
|
||||||
|
// If we're on MIR or Compare mode, don't report AST region errors as they should
|
||||||
|
// be reported by NLL
|
||||||
|
BorrowckMode::Compare | BorrowckMode::Mir => SuppressRegionErrors {
|
||||||
|
suppressed: true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||||
pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
@ -1049,7 +1072,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
region_context: DefId,
|
region_context: DefId,
|
||||||
region_map: ®ion::ScopeTree,
|
region_map: ®ion::ScopeTree,
|
||||||
outlives_env: &OutlivesEnvironment<'tcx>,
|
outlives_env: &OutlivesEnvironment<'tcx>,
|
||||||
unless_nll: UnlessNll,
|
suppress: SuppressRegionErrors,
|
||||||
) {
|
) {
|
||||||
assert!(
|
assert!(
|
||||||
self.is_tainted_by_errors() || self.region_obligations.borrow().is_empty(),
|
self.is_tainted_by_errors() || self.region_obligations.borrow().is_empty(),
|
||||||
@ -1081,7 +1104,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// this infcx was in use. This is totally hokey but
|
// this infcx was in use. This is totally hokey but
|
||||||
// otherwise we have a hard time separating legit region
|
// otherwise we have a hard time separating legit region
|
||||||
// errors from silly ones.
|
// errors from silly ones.
|
||||||
self.report_region_errors(region_map, &errors, unless_nll);
|
self.report_region_errors(region_map, &errors, suppress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ pub use self::ObligationCauseCode::*;
|
|||||||
use chalk_engine;
|
use chalk_engine;
|
||||||
use hir;
|
use hir;
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use infer::UnlessNll;
|
use infer::SuppressRegionErrors;
|
||||||
use infer::outlives::env::OutlivesEnvironment;
|
use infer::outlives::env::OutlivesEnvironment;
|
||||||
use middle::region;
|
use middle::region;
|
||||||
use mir::interpret::ConstEvalErr;
|
use mir::interpret::ConstEvalErr;
|
||||||
@ -720,7 +720,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
region_context,
|
region_context,
|
||||||
®ion_scope_tree,
|
®ion_scope_tree,
|
||||||
&outlives_env,
|
&outlives_env,
|
||||||
UnlessNll(false),
|
SuppressRegionErrors::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let predicates = match infcx.fully_resolve(&predicates) {
|
let predicates = match infcx.fully_resolve(&predicates) {
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
use check::regionck::RegionCtxt;
|
use check::regionck::RegionCtxt;
|
||||||
|
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use rustc::infer::{self, InferOk, UnlessNll};
|
use rustc::infer::{self, InferOk, SuppressRegionErrors};
|
||||||
use rustc::infer::outlives::env::OutlivesEnvironment;
|
use rustc::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc::middle::region;
|
use rustc::middle::region;
|
||||||
use rustc::ty::subst::{Subst, Substs, UnpackedKind};
|
use rustc::ty::subst::{Subst, Substs, UnpackedKind};
|
||||||
@ -128,7 +128,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
|
|||||||
// conservative. -nmatsakis
|
// conservative. -nmatsakis
|
||||||
let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());
|
let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());
|
||||||
|
|
||||||
infcx.resolve_regions_and_report_errors(drop_impl_did, ®ion_scope_tree, &outlives_env, UnlessNll(false));
|
infcx.resolve_regions_and_report_errors(drop_impl_did, ®ion_scope_tree, &outlives_env, SuppressRegionErrors::default());
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -88,8 +88,8 @@ use middle::mem_categorization as mc;
|
|||||||
use middle::mem_categorization::Categorization;
|
use middle::mem_categorization::Categorization;
|
||||||
use middle::region;
|
use middle::region;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::infer::{self, RegionObligation, UnlessNll};
|
|
||||||
use rustc::infer::outlives::env::OutlivesEnvironment;
|
use rustc::infer::outlives::env::OutlivesEnvironment;
|
||||||
|
use rustc::infer::{self, RegionObligation, SuppressRegionErrors};
|
||||||
use rustc::ty::adjustment;
|
use rustc::ty::adjustment;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
@ -140,7 +140,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
rcx.visit_body(body);
|
rcx.visit_body(body);
|
||||||
rcx.visit_region_obligations(id);
|
rcx.visit_region_obligations(id);
|
||||||
}
|
}
|
||||||
rcx.resolve_regions_and_report_errors(UnlessNll(true));
|
rcx.resolve_regions_and_report_errors(SuppressRegionErrors::when_nll_is_enabled(self.tcx));
|
||||||
|
|
||||||
assert!(self.tables.borrow().free_region_map.is_empty());
|
assert!(self.tables.borrow().free_region_map.is_empty());
|
||||||
self.tables.borrow_mut().free_region_map = rcx.outlives_environment.into_free_region_map();
|
self.tables.borrow_mut().free_region_map = rcx.outlives_environment.into_free_region_map();
|
||||||
@ -162,7 +162,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
.add_implied_bounds(self, wf_tys, item_id, span);
|
.add_implied_bounds(self, wf_tys, item_id, span);
|
||||||
rcx.outlives_environment.save_implied_bounds(item_id);
|
rcx.outlives_environment.save_implied_bounds(item_id);
|
||||||
rcx.visit_region_obligations(item_id);
|
rcx.visit_region_obligations(item_id);
|
||||||
rcx.resolve_regions_and_report_errors(UnlessNll(false));
|
rcx.resolve_regions_and_report_errors(SuppressRegionErrors::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Region check a function body. Not invoked on closures, but
|
/// Region check a function body. Not invoked on closures, but
|
||||||
@ -190,7 +190,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
rcx.visit_fn_body(fn_id, body, self.tcx.hir.span(fn_id));
|
rcx.visit_fn_body(fn_id, body, self.tcx.hir.span(fn_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
rcx.resolve_regions_and_report_errors(UnlessNll(true));
|
rcx.resolve_regions_and_report_errors(SuppressRegionErrors::when_nll_is_enabled(self.tcx));
|
||||||
|
|
||||||
// In this mode, we also copy the free-region-map into the
|
// In this mode, we also copy the free-region-map into the
|
||||||
// tables of the enclosing fcx. In the other regionck modes
|
// tables of the enclosing fcx. In the other regionck modes
|
||||||
@ -314,7 +314,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
id: ast::NodeId, // the id of the fn itself
|
id: ast::NodeId, // the id of the fn itself
|
||||||
body: &'gcx hir::Body,
|
body: &'gcx hir::Body,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
// When we enter a function, we can derive
|
// When we enter a function, we can derive
|
||||||
debug!("visit_fn_body(id={})", id);
|
debug!("visit_fn_body(id={})", id);
|
||||||
|
|
||||||
@ -355,7 +355,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
body_id.node_id,
|
body_id.node_id,
|
||||||
span,
|
span,
|
||||||
);
|
);
|
||||||
self.outlives_environment.save_implied_bounds(body_id.node_id);
|
self.outlives_environment
|
||||||
|
.save_implied_bounds(body_id.node_id);
|
||||||
self.link_fn_args(
|
self.link_fn_args(
|
||||||
region::Scope {
|
region::Scope {
|
||||||
id: body.value.hir_id.local_id,
|
id: body.value.hir_id.local_id,
|
||||||
@ -392,7 +393,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
self.select_all_obligations_or_error();
|
self.select_all_obligations_or_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_regions_and_report_errors(&self, unless_nll: UnlessNll) {
|
fn resolve_regions_and_report_errors(&self, suppress: SuppressRegionErrors) {
|
||||||
self.infcx.process_registered_region_obligations(
|
self.infcx.process_registered_region_obligations(
|
||||||
self.outlives_environment.region_bound_pairs_map(),
|
self.outlives_environment.region_bound_pairs_map(),
|
||||||
self.implicit_region_bound,
|
self.implicit_region_bound,
|
||||||
@ -403,7 +404,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
self.subject_def_id,
|
self.subject_def_id,
|
||||||
&self.region_scope_tree,
|
&self.region_scope_tree,
|
||||||
&self.outlives_environment,
|
&self.outlives_environment,
|
||||||
unless_nll,
|
suppress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
//! Check properties that are required by built-in traits and set
|
//! Check properties that are required by built-in traits and set
|
||||||
//! up data structures required by type-checking/codegen.
|
//! up data structures required by type-checking/codegen.
|
||||||
|
|
||||||
use rustc::infer::UnlessNll;
|
use rustc::infer::SuppressRegionErrors;
|
||||||
use rustc::infer::outlives::env::OutlivesEnvironment;
|
use rustc::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc::middle::region;
|
use rustc::middle::region;
|
||||||
use rustc::middle::lang_items::UnsizeTraitLangItem;
|
use rustc::middle::lang_items::UnsizeTraitLangItem;
|
||||||
@ -397,7 +397,7 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>,
|
|||||||
impl_did,
|
impl_did,
|
||||||
®ion_scope_tree,
|
®ion_scope_tree,
|
||||||
&outlives_env,
|
&outlives_env,
|
||||||
UnlessNll(false),
|
SuppressRegionErrors::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
CoerceUnsizedInfo {
|
CoerceUnsizedInfo {
|
||||||
|
Loading…
Reference in New Issue
Block a user