about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-01-23 21:13:14 +0000
committerbors <bors@rust-lang.org>2021-01-23 21:13:14 +0000
commit1279b3b9232e4c44112d98f19cfa8846776d1fe8 (patch)
tree2656f7f38ceb24cc242b3f814288924f8e9bc7ac /compiler
parent4d0dd02ee07bddad9136f95c9f7846ebf3eb3fc5 (diff)
parentebeb6b8b26f78c2c1a412a2e0e65e2e1f5ebc111 (diff)
downloadrust-1279b3b9232e4c44112d98f19cfa8846776d1fe8.tar.gz
rust-1279b3b9232e4c44112d98f19cfa8846776d1fe8.zip
Auto merge of #81304 - jonas-schievink:rollup-d9kuugm, r=jonas-schievink
Rollup of 15 pull requests

Successful merges:

 - #79841 (More clear documentation for NonNull<T>)
 - #81072 (PlaceRef::ty: use method call syntax)
 - #81130 (Edit rustc_middle::dep_graph module documentation)
 - #81170 (Avoid hash_slice in VecDeque's Hash implementation)
 - #81243 (mir: Improve size_of handling when arg is unsized)
 - #81245 (Update cargo)
 - #81249 (Lower closure prototype after its body.)
 - #81252 (Add more self-profile info to rustc_resolve)
 - #81275 (Fix <unknown> queries and add more timing info to render_html)
 - #81281 (Inline methods of Path and OsString)
 - #81283 (Note library tracking issue template in tracking issue template.)
 - #81285 (Remove special casing of rustdoc in rustc_lint)
 - #81288 (rustdoc: Fix visibility of trait and impl items)
 - #81298 (replace RefCell with Cell in FnCtxt)
 - #81301 (Fix small typo)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs31
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs7
-rw-r--r--compiler/rustc_interface/src/queries.rs16
-rw-r--r--compiler/rustc_lint/src/early.rs14
-rw-r--r--compiler/rustc_middle/src/dep_graph/dep_node.rs17
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs3
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs4
-rw-r--r--compiler/rustc_mir/src/borrow_check/mod.rs8
-rw-r--r--compiler/rustc_mir/src/borrow_check/prefixes.rs2
-rw-r--r--compiler/rustc_mir/src/interpret/step.rs1
-rw-r--r--compiler/rustc_resolve/src/lib.rs18
-rw-r--r--compiler/rustc_typeck/src/check/check.rs2
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs10
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs8
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/checks.rs9
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/mod.rs8
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs4
19 files changed, 84 insertions, 82 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 31360158e2b..4d6afd2fe0d 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -776,10 +776,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         body: &Expr,
         fn_decl_span: Span,
     ) -> hir::ExprKind<'hir> {
-        // Lower outside new scope to preserve `is_in_loop_condition`.
-        let fn_decl = self.lower_fn_decl(decl, None, false, None);
-
-        self.with_new_scopes(move |this| {
+        let (body_id, generator_option) = self.with_new_scopes(move |this| {
             let prev = this.current_item;
             this.current_item = Some(fn_decl_span);
             let mut generator_kind = None;
@@ -791,8 +788,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
             let generator_option =
                 this.generator_movability_for_fn(&decl, fn_decl_span, generator_kind, movability);
             this.current_item = prev;
-            hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, generator_option)
-        })
+            (body_id, generator_option)
+        });
+
+        // Lower outside new scope to preserve `is_in_loop_condition`.
+        let fn_decl = self.lower_fn_decl(decl, None, false, None);
+
+        hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, generator_option)
     }
 
     fn generator_movability_for_fn(
@@ -838,12 +840,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
     ) -> hir::ExprKind<'hir> {
         let outer_decl =
             FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
-        // We need to lower the declaration outside the new scope, because we
-        // have to conserve the state of being inside a loop condition for the
-        // closure argument types.
-        let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None);
 
-        self.with_new_scopes(move |this| {
+        let body_id = self.with_new_scopes(|this| {
             // FIXME(cramertj): allow `async` non-`move` closures with arguments.
             if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
                 struct_span_err!(
@@ -874,8 +872,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 );
                 this.expr(fn_decl_span, async_body, ThinVec::new())
             });
-            hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, None)
-        })
+            body_id
+        });
+
+        // We need to lower the declaration outside the new scope, because we
+        // have to conserve the state of being inside a loop condition for the
+        // closure argument types.
+        let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None);
+
+        hir::ExprKind::Closure(capture_clause, fn_decl, body_id, fn_decl_span, None)
     }
 
     /// Destructure the LHS of complex assignments.
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index b1e372afc65..fd0ff5b66e6 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -119,7 +119,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
                 )
             );
             if is_consume {
-                let base_ty = mir::PlaceRef::ty(&place_base, self.fx.mir, cx.tcx());
+                let base_ty = place_base.ty(self.fx.mir, cx.tcx());
                 let base_ty = self.fx.monomorphize(base_ty);
 
                 // ZSTs don't require any actual memory access.
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 958e4ebd078..66d9d1a1e0c 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -506,7 +506,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
     pub fn monomorphized_place_ty(&self, place_ref: mir::PlaceRef<'tcx>) -> Ty<'tcx> {
         let tcx = self.cx.tcx();
-        let place_ty = mir::PlaceRef::ty(&place_ref, self.mir, tcx);
+        let place_ty = place_ref.ty(self.mir, tcx);
         self.monomorphize(place_ty.ty)
     }
 }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index ead2512d3b2..7031234e108 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -1017,13 +1017,6 @@ pub fn start_codegen<'tcx>(
     tcx.sess.time("assert_dep_graph", || rustc_incremental::assert_dep_graph(tcx));
     tcx.sess.time("serialize_dep_graph", || rustc_incremental::save_dep_graph(tcx));
 
-    // We assume that no queries are run past here. If there are new queries
-    // after this point, they'll show up as "<unknown>" in self-profiling data.
-    {
-        let _prof_timer = tcx.prof.generic_activity("self_profile_alloc_query_strings");
-        tcx.alloc_self_profile_query_strings();
-    }
-
     info!("Post-codegen\n{:?}", tcx.debug_stats());
 
     if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) {
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 9c49f926d41..ac6b6d03115 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -417,9 +417,19 @@ impl Compiler {
         let queries = Queries::new(&self);
         let ret = f(&queries);
 
-        if self.session().opts.debugging_opts.query_stats {
-            if let Ok(gcx) = queries.global_ctxt() {
-                gcx.peek_mut().print_stats();
+        // NOTE: intentionally does not compute the global context if it hasn't been built yet,
+        // since that likely means there was a parse error.
+        if let Some(Ok(gcx)) = &mut *queries.global_ctxt.result.borrow_mut() {
+            // We assume that no queries are run past here. If there are new queries
+            // after this point, they'll show up as "<unknown>" in self-profiling data.
+            {
+                let _prof_timer =
+                    queries.session().prof.generic_activity("self_profile_alloc_query_strings");
+                gcx.enter(|tcx| tcx.alloc_self_profile_query_strings());
+            }
+
+            if self.session().opts.debugging_opts.query_stats {
+                gcx.print_stats();
             }
         }
 
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 08c147ec3ac..e36af234936 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -379,17 +379,9 @@ pub fn check_ast_crate<T: EarlyLintPass>(
     // All of the buffered lints should have been emitted at this point.
     // If not, that means that we somehow buffered a lint for a node id
     // that was not lint-checked (perhaps it doesn't exist?). This is a bug.
-    //
-    // Rustdoc runs everybody-loops before the early lints and removes
-    // function bodies, so it's totally possible for linted
-    // node ids to not exist (e.g., macros defined within functions for the
-    // unused_macro lint) anymore. So we only run this check
-    // when we're not in rustdoc mode. (see issue #47639)
-    if !sess.opts.actually_rustdoc {
-        for (_id, lints) in buffered.map {
-            for early_lint in lints {
-                sess.delay_span_bug(early_lint.span, "failed to process buffered lint here");
-            }
+    for (_id, lints) in buffered.map {
+        for early_lint in lints {
+            sess.delay_span_bug(early_lint.span, "failed to process buffered lint here");
         }
     }
 }
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 62f2874af04..1cb75757379 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -1,16 +1,17 @@
-//! This module defines the `DepNode` type which the compiler uses to represent
-//! nodes in the dependency graph.
+//! Nodes in the dependency graph.
 //!
-//! A `DepNode` consists of a `DepKind` (which
-//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc)
-//! and a `Fingerprint`, a 128-bit hash value the exact meaning of which
+//! A node in the [dependency graph] is represented by a [`DepNode`].
+//! A `DepNode` consists of a [`DepKind`] (which
+//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.)
+//! and a [`Fingerprint`], a 128-bit hash value, the exact meaning of which
 //! depends on the node's `DepKind`. Together, the kind and the fingerprint
 //! fully identify a dependency node, even across multiple compilation sessions.
 //! In other words, the value of the fingerprint does not depend on anything
 //! that is specific to a given compilation session, like an unpredictable
-//! interning key (e.g., NodeId, DefId, Symbol) or the numeric value of a
+//! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a
 //! pointer. The concept behind this could be compared to how git commit hashes
-//! uniquely identify a given commit and has a few advantages:
+//! uniquely identify a given commit. The fingerprinting approach has
+//! a few advantages:
 //!
 //! * A `DepNode` can simply be serialized to disk and loaded in another session
 //!   without the need to do any "rebasing" (like we have to do for Spans and
@@ -51,6 +52,8 @@
 //! than a zeroed out fingerprint. More generally speaking, it relieves the
 //! user of the `DepNode` API of having to know how to compute the expected
 //! fingerprint for a given set of node parameters.
+//!
+//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html
 
 use crate::ty::TyCtxt;
 
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 397d2ffd565..cf931ece712 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -127,6 +127,8 @@ pub enum InvalidProgramInfo<'tcx> {
     Layout(layout::LayoutError<'tcx>),
     /// An invalid transmute happened.
     TransmuteSizeDiff(Ty<'tcx>, Ty<'tcx>),
+    /// SizeOf of unsized type was requested.
+    SizeOfUnsizedType(Ty<'tcx>),
 }
 
 impl fmt::Display for InvalidProgramInfo<'_> {
@@ -144,6 +146,7 @@ impl fmt::Display for InvalidProgramInfo<'_> {
                 "transmuting `{}` to `{}` is not possible, because these types do not have the same size",
                 from_ty, to_ty
             ),
+            SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{}`", ty),
         }
     }
 }
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
index 8f41bfae2fd..cd16a88e5fc 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
@@ -289,7 +289,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 );
             }
 
-            let ty = PlaceRef::ty(&used_place, self.body, self.infcx.tcx).ty;
+            let ty = used_place.ty(self.body, self.infcx.tcx).ty;
             let needs_note = match ty.kind() {
                 ty::Closure(id, _) => {
                     let tables = self.infcx.tcx.typeck(id.expect_local());
@@ -728,6 +728,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         // Define a small closure that we can use to check if the type of a place
         // is a union.
         let union_ty = |place_base| {
+            // Need to use fn call syntax `PlaceRef::ty` to determine the type of `place_base`;
+            // using a type annotation in the closure argument instead leads to a lifetime error.
             let ty = PlaceRef::ty(&place_base, self.body, self.infcx.tcx).ty;
             ty.ty_adt_def().filter(|adt| adt.is_union()).map(|_| ty)
         };
diff --git a/compiler/rustc_mir/src/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs
index 006e05072a7..7c7edfdb5fb 100644
--- a/compiler/rustc_mir/src/borrow_check/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/mod.rs
@@ -1743,7 +1743,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         if let Some((place_base, ProjectionElem::Subslice { from, to, from_end: false })) =
             place_span.0.last_projection()
         {
-            let place_ty = PlaceRef::ty(&place_base, self.body(), self.infcx.tcx);
+            let place_ty = place_base.ty(self.body(), self.infcx.tcx);
             if let ty::Array(..) = place_ty.ty.kind() {
                 self.check_if_subslice_element_is_moved(
                     location,
@@ -1854,7 +1854,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     // assigning to `P.f` requires `P` itself
                     // be already initialized
                     let tcx = self.infcx.tcx;
-                    let base_ty = PlaceRef::ty(&place_base, self.body(), tcx).ty;
+                    let base_ty = place_base.ty(self.body(), tcx).ty;
                     match base_ty.kind() {
                         ty::Adt(def, _) if def.has_dtor(tcx) => {
                             self.check_if_path_or_subpath_is_moved(
@@ -1951,7 +1951,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 // no move out from an earlier location) then this is an attempt at initialization
                 // of the union - we should error in that case.
                 let tcx = this.infcx.tcx;
-                if let ty::Adt(def, _) = PlaceRef::ty(&base, this.body(), tcx).ty.kind() {
+                if let ty::Adt(def, _) = base.ty(this.body(), tcx).ty.kind() {
                     if def.is_union() {
                         if this.move_data.path_map[mpi].iter().any(|moi| {
                             this.move_data.moves[*moi].source.is_predecessor_of(location, this.body)
@@ -2173,7 +2173,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             Some((place_base, elem)) => {
                 match elem {
                     ProjectionElem::Deref => {
-                        let base_ty = PlaceRef::ty(&place_base, self.body(), self.infcx.tcx).ty;
+                        let base_ty = place_base.ty(self.body(), self.infcx.tcx).ty;
 
                         // Check the kind of deref to decide
                         match base_ty.kind() {
diff --git a/compiler/rustc_mir/src/borrow_check/prefixes.rs b/compiler/rustc_mir/src/borrow_check/prefixes.rs
index cf04c55eb68..bdf2becb711 100644
--- a/compiler/rustc_mir/src/borrow_check/prefixes.rs
+++ b/compiler/rustc_mir/src/borrow_check/prefixes.rs
@@ -117,7 +117,7 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
                     // derefs, except we stop at the deref of a shared
                     // reference.
 
-                    let ty = PlaceRef::ty(&cursor_base, self.body, self.tcx).ty;
+                    let ty = cursor_base.ty(self.body, self.tcx).ty;
                     match ty.kind() {
                         ty::RawPtr(_) | ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Not) => {
                             // don't continue traversing over derefs of raw pointers or shared
diff --git a/compiler/rustc_mir/src/interpret/step.rs b/compiler/rustc_mir/src/interpret/step.rs
index 6d447acbecf..fbc72ad8adc 100644
--- a/compiler/rustc_mir/src/interpret/step.rs
+++ b/compiler/rustc_mir/src/interpret/step.rs
@@ -270,6 +270,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         self.frame().current_span(),
                         &format!("SizeOf nullary MIR operator called for unsized type {}", ty),
                     );
+                    throw_inval!(SizeOfUnsizedType(ty));
                 }
                 self.write_scalar(Scalar::from_machine_usize(layout.size.bytes(), self), dest)?;
             }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index d293899dc0c..2b4a1d9e3fa 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1465,16 +1465,14 @@ impl<'a> Resolver<'a> {
 
     /// Entry point to crate resolution.
     pub fn resolve_crate(&mut self, krate: &Crate) {
-        let _prof_timer = self.session.prof.generic_activity("resolve_crate");
-
-        ImportResolver { r: self }.finalize_imports();
-        self.finalize_macro_resolutions();
-
-        self.late_resolve_crate(krate);
-
-        self.check_unused(krate);
-        self.report_errors(krate);
-        self.crate_loader.postprocess(krate);
+        self.session.time("resolve_crate", || {
+            self.session.time("finalize_imports", || ImportResolver { r: self }.finalize_imports());
+            self.session.time("finalize_macro_resolutions", || self.finalize_macro_resolutions());
+            self.session.time("late_resolve_crate", || self.late_resolve_crate(krate));
+            self.session.time("resolve_check_unused", || self.check_unused(krate));
+            self.session.time("resolve_report_errors", || self.report_errors(krate));
+            self.session.time("resolve_postprocess", || self.crate_loader.postprocess(krate));
+        });
     }
 
     pub fn traits_in_scope(
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 8e339eb26b2..ab3c26fac83 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -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;
diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index 34ad8ec0898..b2395b7bb25 100644
--- a/compiler/rustc_typeck/src/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
@@ -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)
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 8f463af73c4..e37b4ff742b 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -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) {
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
index 6df9e3ab7db..fb6f9c03352 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
@@ -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
     }
 
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
index 6d09043bd50..e9223f700dc 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
@@ -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 {
diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index 52276ed4bee..c8c6fa12fae 100644
--- a/compiler/rustc_typeck/src/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
@@ -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 {