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