Auto merge of #82536 - sexxi-goose:handle-patterns-take-2, r=nikomatsakis

2229: Handle patterns within closures correctly when `capture_disjoint_fields` is enabled

This PR fixes several issues related to handling patterns within closures when `capture_disjoint_fields` is enabled.
1. Matching is always considered a use of the place, even with `_` patterns
2. Compiler ICE when capturing fields in closures through `let` assignments

To do so, we

- Introduced new Fake Reads
- Delayed use of `Place` in favor of `PlaceBuilder`
- Ensured that `PlaceBuilder` can be resolved before attempting to extract `Place` in any of the pattern matching code

Closes rust-lang/project-rfc-2229/issues/27
Closes rust-lang/project-rfc-2229/issues/24
r? `@nikomatsakis`
This commit is contained in:
bors 2021-03-16 19:19:06 +00:00
commit 846d4f0613
4 changed files with 12 additions and 0 deletions

View file

@ -2,6 +2,7 @@ use rustc_hir::intravisit;
use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node}; use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty::{self, TraitRef, Ty}; use rustc_middle::ty::{self, TraitRef, Ty};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
@ -184,6 +185,8 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
} }
} }
} }
fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _: HirId) { }
} }
impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> { impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {

View file

@ -4,6 +4,7 @@ use if_chain::if_chain;
use rustc_hir::{BindingAnnotation, Expr, HirId, Node, PatKind}; use rustc_hir::{BindingAnnotation, Expr, HirId, Node, PatKind};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
@ -106,6 +107,8 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
} }
} }
} }
fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _:HirId) { }
} }
impl MutatePairDelegate<'_, '_> { impl MutatePairDelegate<'_, '_> {

View file

@ -11,6 +11,7 @@ use rustc_hir::intravisit::FnKind;
use rustc_hir::{BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Node, PatKind, QPath, TyKind}; use rustc_hir::{BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Node, PatKind, QPath, TyKind};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty::{self, TypeFoldable}; use rustc_middle::ty::{self, TypeFoldable};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::kw; use rustc_span::symbol::kw;
@ -333,4 +334,6 @@ impl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt {
fn borrow(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {} fn borrow(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {}
fn mutate(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {} fn mutate(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {}
fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _: HirId) { }
} }

View file

@ -7,6 +7,7 @@ use rustc_hir::intravisit::{NestedVisitorMap, Visitor};
use rustc_hir::{Expr, ExprKind, HirId, Path}; use rustc_hir::{Expr, ExprKind, HirId, Path};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::mir::FakeReadCause;
use rustc_middle::hir::map::Map; use rustc_middle::hir::map::Map;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
@ -77,6 +78,8 @@ impl<'tcx> Delegate<'tcx> for MutVarsDelegate {
fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) { fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) {
self.update(&cmt) self.update(&cmt)
} }
fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _:HirId) { }
} }
pub struct ParamBindingIdCollector { pub struct ParamBindingIdCollector {