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:
Niko Matsakis 2018-09-24 13:05:10 -04:00
parent 0b4791e60b
commit a13c9f6bfd
6 changed files with 54 additions and 39 deletions

View File

@ -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: &region::ScopeTree, region_scope_tree: &region::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

View File

@ -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: &region::ScopeTree, region_map: &region::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);
} }
} }

View File

@ -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,
&region_scope_tree, &region_scope_tree,
&outlives_env, &outlives_env,
UnlessNll(false), SuppressRegionErrors::default(),
); );
let predicates = match infcx.fully_resolve(&predicates) { let predicates = match infcx.fully_resolve(&predicates) {

View File

@ -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, &region_scope_tree, &outlives_env, UnlessNll(false)); infcx.resolve_regions_and_report_errors(drop_impl_did, &region_scope_tree, &outlives_env, SuppressRegionErrors::default());
Ok(()) Ok(())
}) })
} }

View File

@ -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,
); );
} }

View File

@ -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,
&region_scope_tree, &region_scope_tree,
&outlives_env, &outlives_env,
UnlessNll(false), SuppressRegionErrors::default(),
); );
CoerceUnsizedInfo { CoerceUnsizedInfo {