diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index d37c68f82fb..f600325f145 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -943,6 +943,10 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not }; let bk = ty::BorrowKind::from_mutbl(mutability); self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk); + } else if let PatKind::Never = pat.kind { + // A `!` pattern always counts as an immutable read of the discriminant, + // even in an irrefutable pattern. + self.delegate.borrow_mut().borrow(place, discr_place.hir_id, BorrowKind::Immutable); } Ok(()) diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/always-read-in-closure-capture.rs b/tests/ui/rfcs/rfc-0000-never_patterns/always-read-in-closure-capture.rs new file mode 100644 index 00000000000..3c4cd57ec24 --- /dev/null +++ b/tests/ui/rfcs/rfc-0000-never_patterns/always-read-in-closure-capture.rs @@ -0,0 +1,16 @@ +//@ check-pass + +// Make sure that the closure captures `s` so it can perform a read of `s`. + +#![feature(never_patterns)] +#![allow(incomplete_features)] + +enum Void {} + +fn by_value(s: Void) { + move || { + let ! = s; + }; +} + +fn main() {}