replace RefCell with Cell in FnCtxt
This commit is contained in:
parent
1986b58c64
commit
688cf6406a
@ -66,7 +66,7 @@ pub(super) fn check_fn<'a, 'tcx>(
|
||||
// Create the function context. This is either derived from scratch or,
|
||||
// in the case of closures, based on the outer context.
|
||||
let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
|
||||
*fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
|
||||
fcx.ps.set(UnsafetyState::function(fn_sig.unsafety, fn_id));
|
||||
|
||||
let tcx = fcx.tcx;
|
||||
let sess = tcx.sess;
|
||||
|
@ -1472,22 +1472,22 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||
fn_output = Some(&fn_decl.output); // `impl Trait` return type
|
||||
}
|
||||
}
|
||||
if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.borrow().as_ref(), fn_output) {
|
||||
self.add_impl_trait_explanation(&mut err, cause, fcx, expected, *sp, fn_output);
|
||||
if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.get(), fn_output) {
|
||||
self.add_impl_trait_explanation(&mut err, cause, fcx, expected, sp, fn_output);
|
||||
}
|
||||
|
||||
if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() {
|
||||
if let Some(sp) = fcx.ret_coercion_span.get() {
|
||||
// If the closure has an explicit return type annotation,
|
||||
// then a type error may occur at the first return expression we
|
||||
// see in the closure (if it conflicts with the declared
|
||||
// return type). Skip adding a note in this case, since it
|
||||
// would be incorrect.
|
||||
if !err.span.primary_spans().iter().any(|span| span == sp) {
|
||||
if !err.span.primary_spans().iter().any(|&span| span == sp) {
|
||||
let hir = fcx.tcx.hir();
|
||||
let body_owner = hir.body_owned_by(hir.enclosing_body_owner(fcx.body_id));
|
||||
if fcx.tcx.is_closure(hir.body_owner_def_id(body_owner).to_def_id()) {
|
||||
err.span_note(
|
||||
*sp,
|
||||
sp,
|
||||
&format!(
|
||||
"return type inferred to be `{}` here",
|
||||
fcx.resolve_vars_if_possible(expected)
|
||||
|
@ -680,14 +680,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if self.ret_coercion.is_none() {
|
||||
self.tcx.sess.emit_err(ReturnStmtOutsideOfFnBody { span: expr.span });
|
||||
} else if let Some(ref e) = expr_opt {
|
||||
if self.ret_coercion_span.borrow().is_none() {
|
||||
*self.ret_coercion_span.borrow_mut() = Some(e.span);
|
||||
if self.ret_coercion_span.get().is_none() {
|
||||
self.ret_coercion_span.set(Some(e.span));
|
||||
}
|
||||
self.check_return_expr(e);
|
||||
} else {
|
||||
let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
|
||||
if self.ret_coercion_span.borrow().is_none() {
|
||||
*self.ret_coercion_span.borrow_mut() = Some(expr.span);
|
||||
if self.ret_coercion_span.get().is_none() {
|
||||
self.ret_coercion_span.set(Some(expr.span));
|
||||
}
|
||||
let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
|
||||
if let Some((fn_decl, _)) = self.get_fn_decl(expr.hir_id) {
|
||||
|
@ -23,7 +23,6 @@ use rustc_span::{self, MultiSpan, Span};
|
||||
use rustc_trait_selection::traits::{self, ObligationCauseCode, StatementAsExpression};
|
||||
|
||||
use crate::structured_errors::StructuredDiagnostic;
|
||||
use std::mem::replace;
|
||||
use std::slice;
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
@ -589,11 +588,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
blk: &'tcx hir::Block<'tcx>,
|
||||
expected: Expectation<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let prev = {
|
||||
let mut fcx_ps = self.ps.borrow_mut();
|
||||
let unsafety_state = fcx_ps.recurse(blk);
|
||||
replace(&mut *fcx_ps, unsafety_state)
|
||||
};
|
||||
let prev = self.ps.replace(self.ps.get().recurse(blk));
|
||||
|
||||
// In some cases, blocks have just one exit, but other blocks
|
||||
// can be targeted by multiple breaks. This can happen both
|
||||
@ -709,7 +704,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
self.write_ty(blk.hir_id, ty);
|
||||
|
||||
*self.ps.borrow_mut() = prev;
|
||||
self.ps.set(prev);
|
||||
ty
|
||||
}
|
||||
|
||||
|
@ -66,11 +66,11 @@ pub struct FnCtxt<'a, 'tcx> {
|
||||
pub(super) in_tail_expr: bool,
|
||||
|
||||
/// First span of a return site that we find. Used in error messages.
|
||||
pub(super) ret_coercion_span: RefCell<Option<Span>>,
|
||||
pub(super) ret_coercion_span: Cell<Option<Span>>,
|
||||
|
||||
pub(super) resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
|
||||
|
||||
pub(super) ps: RefCell<UnsafetyState>,
|
||||
pub(super) ps: Cell<UnsafetyState>,
|
||||
|
||||
/// Whether the last checked node generates a divergence (e.g.,
|
||||
/// `return` will set this to `Always`). In general, when entering
|
||||
@ -127,9 +127,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ret_coercion_impl_trait: None,
|
||||
ret_type_span: None,
|
||||
in_tail_expr: false,
|
||||
ret_coercion_span: RefCell::new(None),
|
||||
ret_coercion_span: Cell::new(None),
|
||||
resume_yield_tys: None,
|
||||
ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
|
||||
ps: Cell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
|
||||
diverges: Cell::new(Diverges::Maybe),
|
||||
has_errors: Cell::new(false),
|
||||
enclosing_breakables: RefCell::new(EnclosingBreakables {
|
||||
|
@ -184,14 +184,14 @@ impl UnsafetyState {
|
||||
UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
|
||||
}
|
||||
|
||||
pub fn recurse(&mut self, blk: &hir::Block<'_>) -> UnsafetyState {
|
||||
pub fn recurse(self, blk: &hir::Block<'_>) -> UnsafetyState {
|
||||
use hir::BlockCheckMode;
|
||||
match self.unsafety {
|
||||
// If this unsafe, then if the outer function was already marked as
|
||||
// unsafe we shouldn't attribute the unsafe'ness to the block. This
|
||||
// way the block can be warned about instead of ignoring this
|
||||
// extraneous block (functions are never warned about).
|
||||
hir::Unsafety::Unsafe if self.from_fn => *self,
|
||||
hir::Unsafety::Unsafe if self.from_fn => self,
|
||||
|
||||
unsafety => {
|
||||
let (unsafety, def, count) = match blk.rules {
|
||||
|
Loading…
Reference in New Issue
Block a user