about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-08-05 14:45:09 +0000
committerbors <bors@rust-lang.org>2021-08-05 14:45:09 +0000
commit61a941b8badbce727085c505068d72fa3e737f5b (patch)
treedd8f7bad1a1277d6fc47e0bf78ad1db40321af27
parente21e1d6a417330af5f4693004230fd0efdf9445a (diff)
parent2b169ccc9611ce92d3c5d747fbd99c3e7a990cf0 (diff)
downloadrust-61a941b8badbce727085c505068d72fa3e737f5b.tar.gz
rust-61a941b8badbce727085c505068d72fa3e737f5b.zip
Auto merge of #87737 - LeSeulArtichaut:unsafeck-less-freeze, r=oli-obk
Only compute `is_freeze` for layout-constrained ADTs

Places are usually shallow and quick to visit. By contrast, computing `is_freeze` can be much costlier, involving inference and trait solving. Making sure to call `is_freeze` only when necessary should be beneficial for performance in most cases.

See [this comparison](https://perf.rust-lang.org/compare.html?start=81f08a4763e7537b92506fa5a597e6bf774d20cc&end=56a58d347b1c7dd0c2984b8fc3930c408e26fbc2&stat=instructions%3Au) from #87710.

r? `@oli-obk`
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs34
1 files changed, 16 insertions, 18 deletions
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index d27ce6ec81a..42e4fc3839e 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -456,27 +456,25 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     return; // we have already visited everything by now
                 }
             }
-            ExprKind::Borrow { borrow_kind, arg } => match borrow_kind {
-                BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {
-                    if !self.thir[arg]
-                        .ty
-                        .is_freeze(self.tcx.at(self.thir[arg].span), self.param_env)
-                    {
-                        let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx);
-                        visit::walk_expr(&mut visitor, expr);
-                        if visitor.found {
-                            self.requires_unsafe(expr.span, BorrowOfLayoutConstrainedField);
+            ExprKind::Borrow { borrow_kind, arg } => {
+                let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx);
+                visit::walk_expr(&mut visitor, expr);
+                if visitor.found {
+                    match borrow_kind {
+                        BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique
+                            if !self.thir[arg]
+                                .ty
+                                .is_freeze(self.tcx.at(self.thir[arg].span), self.param_env) =>
+                        {
+                            self.requires_unsafe(expr.span, BorrowOfLayoutConstrainedField)
                         }
+                        BorrowKind::Mut { .. } => {
+                            self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField)
+                        }
+                        BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {}
                     }
                 }
-                BorrowKind::Mut { .. } => {
-                    let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx);
-                    visit::walk_expr(&mut visitor, expr);
-                    if visitor.found {
-                        self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
-                    }
-                }
-            },
+            }
             _ => {}
         }
         visit::walk_expr(self, expr);