2229 migration: Don't try resolve regions before writeback

In the analysis use `resolve_vars_if_possible` instead of `fully_resolve`,
because we might not have performed regionck yet.

Fixes: #83176
This commit is contained in:
Aman Arora 2021-03-22 00:45:38 -04:00
parent 97663b6690
commit 74d7731c5b
4 changed files with 29 additions and 19 deletions

View File

@ -30,7 +30,6 @@
//! then mean that all later passes would have to check for these figments //! then mean that all later passes would have to check for these figments
//! and report an error, and it just seems like more mess in the end.) //! and report an error, and it just seems like more mess in the end.)
use super::writeback::Resolver;
use super::FnCtxt; use super::FnCtxt;
use crate::expr_use_visitor as euv; use crate::expr_use_visitor as euv;
@ -42,7 +41,6 @@
use rustc_infer::infer::UpvarRegion; use rustc_infer::infer::UpvarRegion;
use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, ProjectionKind}; use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, ProjectionKind};
use rustc_middle::mir::FakeReadCause; use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeckResults, UpvarSubsts}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeckResults, UpvarSubsts};
use rustc_session::lint; use rustc_session::lint;
use rustc_span::sym; use rustc_span::sym;
@ -167,7 +165,7 @@ fn analyze_closure(
let closure_hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id); let closure_hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
if should_do_migration_analysis(self.tcx, closure_hir_id) { if should_do_migration_analysis(self.tcx, closure_hir_id) {
self.perform_2229_migration_anaysis(closure_def_id, capture_clause, span, body); self.perform_2229_migration_anaysis(closure_def_id, capture_clause, span);
} }
// We now fake capture information for all variables that are mentioned within the closure // We now fake capture information for all variables that are mentioned within the closure
@ -467,13 +465,11 @@ fn perform_2229_migration_anaysis(
closure_def_id: DefId, closure_def_id: DefId,
capture_clause: hir::CaptureBy, capture_clause: hir::CaptureBy,
span: Span, span: Span,
body: &'tcx hir::Body<'tcx>,
) { ) {
let need_migrations = self.compute_2229_migrations( let need_migrations = self.compute_2229_migrations(
closure_def_id, closure_def_id,
span, span,
capture_clause, capture_clause,
body,
self.typeck_results.borrow().closure_min_captures.get(&closure_def_id), self.typeck_results.borrow().closure_min_captures.get(&closure_def_id),
); );
@ -511,19 +507,8 @@ fn compute_2229_migrations(
closure_def_id: DefId, closure_def_id: DefId,
closure_span: Span, closure_span: Span,
closure_clause: hir::CaptureBy, closure_clause: hir::CaptureBy,
body: &'tcx hir::Body<'tcx>,
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
) -> Vec<hir::HirId> { ) -> Vec<hir::HirId> {
fn resolve_ty<T: TypeFoldable<'tcx>>(
fcx: &FnCtxt<'_, 'tcx>,
span: Span,
body: &'tcx hir::Body<'tcx>,
ty: T,
) -> T {
let mut resolver = Resolver::new(fcx, &span, body);
ty.fold_with(&mut resolver)
}
let upvars = if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) { let upvars = if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) {
upvars upvars
} else { } else {
@ -533,7 +518,7 @@ fn resolve_ty<T: TypeFoldable<'tcx>>(
let mut need_migrations = Vec::new(); let mut need_migrations = Vec::new();
for (&var_hir_id, _) in upvars.iter() { for (&var_hir_id, _) in upvars.iter() {
let ty = resolve_ty(self, closure_span, body, self.node_ty(var_hir_id)); let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
if !ty.needs_drop(self.tcx, self.tcx.param_env(closure_def_id.expect_local())) { if !ty.needs_drop(self.tcx, self.tcx.param_env(closure_def_id.expect_local())) {
continue; continue;

View File

@ -675,7 +675,7 @@ fn to_span(&self, tcx: TyCtxt<'_>) -> Span {
/// The Resolver. This is the type folding engine that detects /// The Resolver. This is the type folding engine that detects
/// unresolved types and so forth. /// unresolved types and so forth.
crate struct Resolver<'cx, 'tcx> { struct Resolver<'cx, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
infcx: &'cx InferCtxt<'cx, 'tcx>, infcx: &'cx InferCtxt<'cx, 'tcx>,
span: &'cx dyn Locatable, span: &'cx dyn Locatable,
@ -686,7 +686,7 @@ fn to_span(&self, tcx: TyCtxt<'_>) -> Span {
} }
impl<'cx, 'tcx> Resolver<'cx, 'tcx> { impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
crate fn new( fn new(
fcx: &'cx FnCtxt<'cx, 'tcx>, fcx: &'cx FnCtxt<'cx, 'tcx>,
span: &'cx dyn Locatable, span: &'cx dyn Locatable,
body: &'tcx hir::Body<'tcx>, body: &'tcx hir::Body<'tcx>,

View File

@ -0,0 +1,10 @@
// run-pass
#![warn(disjoint_capture_drop_reorder)]
fn main() {
if let a = "" {
//~^ WARNING: irrefutable `if let` pattern
drop(|_: ()| drop(a));
}
}

View File

@ -0,0 +1,15 @@
warning: irrefutable `if let` pattern
--> $DIR/issue-78720.rs:6:5
|
LL | / if let a = "" {
LL | |
LL | | drop(|_: ()| drop(a));
LL | | }
| |_____^
|
= note: `#[warn(irrefutable_let_patterns)]` on by default
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
warning: 1 warning emitted