Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 15 pull requests #81304

Merged
merged 31 commits into from
Jan 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
1b09dc2
PlaceRef::ty: use method call syntax
RalfJung Jan 16, 2021
ae3a515
Avoid hash_slice in VecDeque's Hash implementation
KamilaBorowska Jan 18, 2021
453ebbd
Update cargo
ehuss Jan 21, 2021
e3faeb4
mir: Improve size_of handling when arg is unsized
osa1 Jan 21, 2021
3f42abe
Lower closure prototype after its body.
cjgillot Jan 21, 2021
5f74ab4
Add more self-profile info to rustc_resolve
jyn514 Jan 21, 2021
9880560
Inline methods of Path and OsString
a1phyr Jan 22, 2021
4d7e489
Note library tracking issue template in tracking issue template.
m-ou-se Jan 22, 2021
0392085
More clear documentation for NonNull<T>
fintelia Dec 8, 2020
0679a4c
Remove special casing of rustdoc in rustc_lint
jyn514 Jan 22, 2021
b29353a
Edit rustc_middle::dep_graph module documentation
pierwill Jan 17, 2021
bf86fd5
Fix <unknown> queries
jyn514 Jan 22, 2021
93e51b1
rustdoc: Fix visibility of trait and impl items
camelid Jan 22, 2021
688cf64
replace RefCell with Cell in FnCtxt
lcnr Jan 23, 2021
1d1010f
Add more timing info to render_html
jyn514 Jan 22, 2021
ca72f9e
Calculate self-profile strings in `Compiler::enter` instead in codegen
jyn514 Jan 22, 2021
2f5ce8e
Fix small typo
davidgu Jan 23, 2021
7635462
Rollup merge of #79841 - fintelia:patch-6, r=kennytm
jonas-schievink Jan 23, 2021
3382771
Rollup merge of #81072 - RalfJung:place-ref-ty, r=oli-obk
jonas-schievink Jan 23, 2021
57d6553
Rollup merge of #81130 - pierwill:edit-depnode, r=jyn514
jonas-schievink Jan 23, 2021
05a95a4
Rollup merge of #81170 - xfix:vecdeque-bug-fix, r=sfackler
jonas-schievink Jan 23, 2021
3a3470b
Rollup merge of #81243 - osa1:fix_80742_2, r=RalfJung
jonas-schievink Jan 23, 2021
c4830da
Rollup merge of #81245 - ehuss:update-cargo, r=ehuss
jonas-schievink Jan 23, 2021
fcf1129
Rollup merge of #81249 - cjgillot:issue-79537, r=oli-obk
jonas-schievink Jan 23, 2021
7038bb1
Rollup merge of #81252 - jyn514:resolve-timing, r=petrochenkov
jonas-schievink Jan 23, 2021
81647c6
Rollup merge of #81275 - jyn514:time-render, r=wesleywiser
jonas-schievink Jan 23, 2021
44c668c
Rollup merge of #81281 - a1phyr:inline_path, r=dtolnay
jonas-schievink Jan 23, 2021
81b0c3e
Rollup merge of #81283 - m-ou-se:tracking-issue-note, r=Mark-Simulacrum
jonas-schievink Jan 23, 2021
64cf8c2
Rollup merge of #81288 - camelid:fix-trait-item-vis, r=jyn514
jonas-schievink Jan 23, 2021
be3723c
Rollup merge of #81298 - lcnr:big-money-big-prices, r=oli-obk
jonas-schievink Jan 23, 2021
ebeb6b8
Rollup merge of #81301 - davidgu:patch-1, r=jonas-schievink
jonas-schievink Jan 23, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/ISSUE_TEMPLATE/tracking_issue.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ title: Tracking Issue for XXX
labels: C-tracking-issue
---
<!--
NOTE: For library features, please use the "Library Tracking Issue" template instead.

Thank you for creating a tracking issue! 📜 Tracking issues are for tracking a
feature from implementation to stabilisation. Make sure to include the relevant
RFC for the feature if it has one. Otherwise provide a short summary of the
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ dependencies = [
"remove_dir_all",
"serde_json",
"tar",
"toml",
"url 2.1.1",
]

Expand Down
31 changes: 18 additions & 13 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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(
Expand Down Expand Up @@ -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!(
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
16 changes: 13 additions & 3 deletions compiler/rustc_interface/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}

Expand Down
14 changes: 3 additions & 11 deletions compiler/rustc_lint/src/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
}
17 changes: 10 additions & 7 deletions compiler/rustc_middle/src/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;

Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<'_> {
Expand All @@ -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),
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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)
};
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_mir/src/borrow_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/borrow_check/prefixes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir/src/interpret/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
}
Expand Down
18 changes: 8 additions & 10 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_typeck/src/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
9 changes: 2 additions & 7 deletions compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand Down
Loading