summary refs log tree commit diff
path: root/compiler/rustc_session/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-10-11 16:46:03 +0000
committerbors <bors@rust-lang.org>2023-10-11 16:46:03 +0000
commitc1691db366c0f2e2341c60377c248ca2d9335076 (patch)
treed4d581a8671c9723e18750b181bf7979607f9ee9 /compiler/rustc_session/src
parent3c23df49352264938a726f6a586d6019e602c5cf (diff)
parent3dcff0051a87dea2a9a319c45c0df57acd29cdca (diff)
downloadrust-c1691db366c0f2e2341c60377c248ca2d9335076.tar.gz
rust-c1691db366c0f2e2341c60377c248ca2d9335076.zip
Auto merge of #113218 - lqd:polonius-scopes, r=jackh726
Compute NLL loan scopes using the polonius model

For a *location-insensitive* analysis (that is, without expressiveness improvements for users yet), this PR implements loans going out of scope using reachability and liveness, rather than checking if the issuing region's values contain a given CFG point. This is equivalent to NLL scopes and computes the same data.

r? `@matthewjasper`

A couple of notes:
- there are some assumptions about SCC representatives, placeholders, free regions, and member constraints that I believe hold, and they're documented in the code
- this passes all the UI tests with `-Zpolonius=next` -- the perf is [not terrible](https://github.com/rust-lang/rust/pull/112432#issuecomment-1749685862) and there are a bunch of ways to improve it in the future.
- there's a fixme left, hopefully Matthew you know a clean way to get the information it mentions.
Diffstat (limited to 'compiler/rustc_session/src')
-rw-r--r--compiler/rustc_session/src/config.rs34
-rw-r--r--compiler/rustc_session/src/options.rs18
2 files changed, 51 insertions, 1 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 8152ace8642..58461856eb1 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -3172,6 +3172,7 @@ impl PpMode {
 /// we have an opt-in scheme here, so one is hopefully forced to think about
 /// how the hash should be calculated when adding a new command-line argument.
 pub(crate) mod dep_tracking {
+    use super::Polonius;
     use super::{
         BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, DebugInfoCompression,
         ErrorOutputType, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
@@ -3281,6 +3282,7 @@ pub(crate) mod dep_tracking {
         OomStrategy,
         LanguageIdentifier,
         TraitSolver,
+        Polonius,
     );
 
     impl<T1, T2> DepTrackingHash for (T1, T2)
@@ -3419,3 +3421,35 @@ impl DumpMonoStatsFormat {
         }
     }
 }
+
+/// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy,
+/// or future prototype.
+#[derive(Clone, Copy, PartialEq, Hash, Debug)]
+pub enum Polonius {
+    /// The default value: disabled.
+    Off,
+
+    /// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`.
+    Legacy,
+
+    /// In-tree prototype, extending the NLL infrastructure.
+    Next,
+}
+
+impl Default for Polonius {
+    fn default() -> Self {
+        Polonius::Off
+    }
+}
+
+impl Polonius {
+    /// Returns whether the legacy version of polonius is enabled
+    pub fn is_legacy_enabled(&self) -> bool {
+        matches!(self, Polonius::Legacy)
+    }
+
+    /// Returns whether the "next" version of polonius is enabled
+    pub fn is_next_enabled(&self) -> bool {
+        matches!(self, Polonius::Next)
+    }
+}
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index ee2a64c98de..eb1aa6d6c88 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -414,6 +414,7 @@ mod desc {
         "one of supported split dwarf modes (`split` or `single`)";
     pub const parse_link_self_contained: &str = "one of: `y`, `yes`, `on`, `n`, `no`, `off`, or a list of enabled (`+` prefix) and disabled (`-` prefix) \
         components: `crto`, `libc`, `unwind`, `linker`, `sanitizers`, `mingw`";
+    pub const parse_polonius: &str = "either no value or `legacy` (the default), or `next`";
     pub const parse_stack_protector: &str =
         "one of (`none` (default), `basic`, `strong`, or `all`)";
     pub const parse_branch_protection: &str =
@@ -471,6 +472,21 @@ mod parse {
         }
     }
 
+    /// Parses whether polonius is enabled, and if so, which version.
+    pub(crate) fn parse_polonius(slot: &mut Polonius, v: Option<&str>) -> bool {
+        match v {
+            Some("legacy") | None => {
+                *slot = Polonius::Legacy;
+                true
+            }
+            Some("next") => {
+                *slot = Polonius::Next;
+                true
+            }
+            _ => false,
+        }
+    }
+
     /// Use this for any string option that has a static default.
     pub(crate) fn parse_string(slot: &mut String, v: Option<&str>) -> bool {
         match v {
@@ -1659,7 +1675,7 @@ options! {
         "whether to use the PLT when calling into shared libraries;
         only has effect for PIC code on systems with ELF binaries
         (default: PLT is disabled if full relro is enabled on x86_64)"),
-    polonius: bool = (false, parse_bool, [TRACKED],
+    polonius: Polonius = (Polonius::default(), parse_polonius, [TRACKED],
         "enable polonius-based borrow-checker (default: no)"),
     polymorphize: bool = (false, parse_bool, [TRACKED],
           "perform polymorphization analysis"),