From 74d7731c5b8f6557099b55378881699cd76175b3 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Mon, 22 Mar 2021 00:45:38 -0400 Subject: [PATCH] 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 --- compiler/rustc_typeck/src/check/upvar.rs | 19 ++----------------- compiler/rustc_typeck/src/check/writeback.rs | 4 ++-- .../migrations/issue-78720.rs | 10 ++++++++++ .../migrations/issue-78720.stderr | 15 +++++++++++++++ 4 files changed, 29 insertions(+), 19 deletions(-) create mode 100644 src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.rs create mode 100644 src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 8a4c69b5ac8f9..5a939cc24f5d6 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -30,7 +30,6 @@ //! 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.) -use super::writeback::Resolver; use super::FnCtxt; use crate::expr_use_visitor as euv; @@ -42,7 +41,6 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_infer::infer::UpvarRegion; use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, ProjectionKind}; use rustc_middle::mir::FakeReadCause; -use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, Ty, TyCtxt, TypeckResults, UpvarSubsts}; use rustc_session::lint; use rustc_span::sym; @@ -167,7 +165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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) { - 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 @@ -467,13 +465,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { closure_def_id: DefId, capture_clause: hir::CaptureBy, span: Span, - body: &'tcx hir::Body<'tcx>, ) { let need_migrations = self.compute_2229_migrations( closure_def_id, span, capture_clause, - body, self.typeck_results.borrow().closure_min_captures.get(&closure_def_id), ); @@ -511,19 +507,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { closure_def_id: DefId, closure_span: Span, closure_clause: hir::CaptureBy, - body: &'tcx hir::Body<'tcx>, min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, ) -> Vec { - fn resolve_ty>( - 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) { upvars } else { @@ -533,7 +518,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut need_migrations = Vec::new(); 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())) { continue; diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index 9a183ed9e629e..e472add6e80f3 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -675,7 +675,7 @@ impl Locatable for hir::HirId { /// The Resolver. This is the type folding engine that detects /// unresolved types and so forth. -crate struct Resolver<'cx, 'tcx> { +struct Resolver<'cx, 'tcx> { tcx: TyCtxt<'tcx>, infcx: &'cx InferCtxt<'cx, 'tcx>, span: &'cx dyn Locatable, @@ -686,7 +686,7 @@ crate struct Resolver<'cx, 'tcx> { } impl<'cx, 'tcx> Resolver<'cx, 'tcx> { - crate fn new( + fn new( fcx: &'cx FnCtxt<'cx, 'tcx>, span: &'cx dyn Locatable, body: &'tcx hir::Body<'tcx>, diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.rs b/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.rs new file mode 100644 index 0000000000000..3a6af00254c5a --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.rs @@ -0,0 +1,10 @@ +// run-pass + +#![warn(disjoint_capture_drop_reorder)] + +fn main() { + if let a = "" { + //~^ WARNING: irrefutable `if let` pattern + drop(|_: ()| drop(a)); + } +} diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr new file mode 100644 index 0000000000000..7e5da949cb299 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr @@ -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 +