about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-06-30 18:41:55 +0200
committerLukas Wirth <lukastw97@gmail.com>2024-06-30 18:41:55 +0200
commitd40bc51e3dbe9a33bb3ed262c934d330f4bed488 (patch)
tree06aa74938a25fdd03debe5e69467f6d5bb4fbf55
parent1653889bad4ab93d0fc461d92e382e15d3288400 (diff)
downloadrust-d40bc51e3dbe9a33bb3ed262c934d330f4bed488.tar.gz
rust-d40bc51e3dbe9a33bb3ed262c934d330f4bed488.zip
Bump rustc_pattern_analysis
-rw-r--r--src/tools/rust-analyzer/Cargo.lock37
-rw-r--r--src/tools/rust-analyzer/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs127
4 files changed, 76 insertions, 92 deletions
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 78270e6d196..f30f69eb6eb 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -616,7 +616,7 @@ dependencies = [
  "oorandom",
  "project-model",
  "ra-ap-rustc_abi",
- "ra-ap-rustc_index 0.53.0",
+ "ra-ap-rustc_index",
  "ra-ap-rustc_pattern_analysis",
  "rustc-hash",
  "scoped-tls",
@@ -1489,46 +1489,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "80b1d613eee933486c0613a7bc26e515e46f43adf479d1edd5e537f983e9ce46"
 dependencies = [
  "bitflags 2.5.0",
- "ra-ap-rustc_index 0.53.0",
+ "ra-ap-rustc_index",
  "tracing",
 ]
 
 [[package]]
 name = "ra-ap-rustc_index"
-version = "0.44.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ad68bacffb87dcdbb23a3ce11261375078aaa06b85d348c49f39ffd5510dc20"
-dependencies = [
- "arrayvec",
- "ra-ap-rustc_index_macros 0.44.0",
- "smallvec",
-]
-
-[[package]]
-name = "ra-ap-rustc_index"
 version = "0.53.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f072060ac77e9e1a02cc20028095993af7e72cc0804779c68bcbf47b16de49c9"
 dependencies = [
  "arrayvec",
- "ra-ap-rustc_index_macros 0.53.0",
+ "ra-ap-rustc_index_macros",
  "smallvec",
 ]
 
 [[package]]
 name = "ra-ap-rustc_index_macros"
-version = "0.44.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8782aaf3a113837c533dfb1c45df91cd17e1fdd1d2f9a20c2e0d1976025c4f1f"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "synstructure",
-]
-
-[[package]]
-name = "ra-ap-rustc_index_macros"
 version = "0.53.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "82f3d6dcb30a66905388e14756b8f2216131d9f8004922c07f13335840e058d1"
@@ -1555,17 +1532,17 @@ version = "0.53.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "70dad7a491c2554590222e0c9212dcb7c2e7aceb668875075012a35ea780d135"
 dependencies = [
- "ra-ap-rustc_index 0.53.0",
+ "ra-ap-rustc_index",
  "ra-ap-rustc_lexer",
 ]
 
 [[package]]
 name = "ra-ap-rustc_pattern_analysis"
-version = "0.44.0"
+version = "0.53.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d63d1e1d5b2a13273cee1a10011147418f40e12b70f70578ce1dee0f1cafc334"
+checksum = "34768e1faf88c31f2e9ad57b48318a52b507dafac0cddbf01b5d63bfc0b0a365"
 dependencies = [
- "ra-ap-rustc_index 0.44.0",
+ "ra-ap-rustc_index",
  "rustc-hash",
  "rustc_apfloat",
  "smallvec",
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index d77804a418e..eea73ac380d 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -87,7 +87,7 @@ ra-ap-rustc_lexer = { version = "0.53.0", default-features = false }
 ra-ap-rustc_parse_format = { version = "0.53.0", default-features = false }
 ra-ap-rustc_index = { version = "0.53.0", default-features = false }
 ra-ap-rustc_abi = { version = "0.53.0", default-features = false }
-ra-ap-rustc_pattern_analysis = { version = "0.44.0", default-features = false }
+ra-ap-rustc_pattern_analysis = { version = "0.53.0", default-features = false }
 
 # local crates that aren't published to crates.io. These should not have versions.
 sourcegen = { path = "./crates/sourcegen" }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
index 8d6e502c6ab..8dcc14feb27 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
@@ -51,6 +51,7 @@ pub(crate) struct Pat {
 #[derive(Clone, Debug, PartialEq)]
 pub(crate) enum PatKind {
     Wild,
+    Never,
 
     /// `x`, `ref x`, `x @ P`, etc.
     Binding {
@@ -294,6 +295,7 @@ impl HirDisplay for Pat {
     fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
         match &*self.kind {
             PatKind::Wild => write!(f, "_"),
+            PatKind::Never => write!(f, "!"),
             PatKind::Binding { name, subpattern } => {
                 write!(f, "{}", name.display(f.db.upcast()))?;
                 if let Some(subpattern) = subpattern {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
index c171dbc1700..01e43a67e43 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
@@ -4,10 +4,9 @@ use std::fmt;
 
 use hir_def::{DefWithBodyId, EnumId, EnumVariantId, HasModule, LocalFieldId, ModuleId, VariantId};
 use once_cell::unsync::Lazy;
-use rustc_hash::FxHashMap;
+use rustc_index::IndexVec;
 use rustc_pattern_analysis::{
     constructor::{Constructor, ConstructorSet, VariantVisibility},
-    index::IdxContainer,
     usefulness::{compute_match_usefulness, PlaceValidity, UsefulnessReport},
     Captures, PatCx, PrivateUninhabitedField,
 };
@@ -26,10 +25,10 @@ use super::{is_box, FieldPat, Pat, PatKind};
 use Constructor::*;
 
 // Re-export r-a-specific versions of all these types.
-pub(crate) type DeconstructedPat<'p> =
-    rustc_pattern_analysis::pat::DeconstructedPat<MatchCheckCtx<'p>>;
-pub(crate) type MatchArm<'p> = rustc_pattern_analysis::MatchArm<'p, MatchCheckCtx<'p>>;
-pub(crate) type WitnessPat<'p> = rustc_pattern_analysis::pat::WitnessPat<MatchCheckCtx<'p>>;
+pub(crate) type DeconstructedPat<'db> =
+    rustc_pattern_analysis::pat::DeconstructedPat<MatchCheckCtx<'db>>;
+pub(crate) type MatchArm<'db> = rustc_pattern_analysis::MatchArm<'db, MatchCheckCtx<'db>>;
+pub(crate) type WitnessPat<'db> = rustc_pattern_analysis::pat::WitnessPat<MatchCheckCtx<'db>>;
 
 /// [Constructor] uses this in unimplemented variants.
 /// It allows porting match expressions from upstream algorithm without losing semantics.
@@ -54,23 +53,27 @@ impl EnumVariantContiguousIndex {
     }
 }
 
+impl rustc_index::Idx for EnumVariantContiguousIndex {
+    fn new(idx: usize) -> Self {
+        EnumVariantContiguousIndex(idx)
+    }
+
+    fn index(self) -> usize {
+        self.0
+    }
+}
+
 #[derive(Clone)]
-pub(crate) struct MatchCheckCtx<'p> {
+pub(crate) struct MatchCheckCtx<'db> {
     module: ModuleId,
     body: DefWithBodyId,
-    pub(crate) db: &'p dyn HirDatabase,
+    pub(crate) db: &'db dyn HirDatabase,
     exhaustive_patterns: bool,
     min_exhaustive_patterns: bool,
 }
 
-#[derive(Clone)]
-pub(crate) struct PatData<'p> {
-    /// Keep db around so that we can print variant names in `Debug`.
-    pub(crate) db: &'p dyn HirDatabase,
-}
-
-impl<'p> MatchCheckCtx<'p> {
-    pub(crate) fn new(module: ModuleId, body: DefWithBodyId, db: &'p dyn HirDatabase) -> Self {
+impl<'db> MatchCheckCtx<'db> {
+    pub(crate) fn new(module: ModuleId, body: DefWithBodyId, db: &'db dyn HirDatabase) -> Self {
         let def_map = db.crate_def_map(module.krate());
         let exhaustive_patterns = def_map.is_unstable_feature_enabled("exhaustive_patterns");
         let min_exhaustive_patterns =
@@ -80,9 +83,9 @@ impl<'p> MatchCheckCtx<'p> {
 
     pub(crate) fn compute_match_usefulness(
         &self,
-        arms: &[MatchArm<'p>],
+        arms: &[MatchArm<'db>],
         scrut_ty: Ty,
-    ) -> Result<UsefulnessReport<'p, Self>, ()> {
+    ) -> Result<UsefulnessReport<'db, Self>, ()> {
         // FIXME: Determine place validity correctly. For now, err on the safe side.
         let place_validity = PlaceValidity::MaybeInvalid;
         // Measured to take ~100ms on modern hardware.
@@ -101,7 +104,7 @@ impl<'p> MatchCheckCtx<'p> {
     }
 
     fn variant_id_for_adt(
-        db: &'p dyn HirDatabase,
+        db: &'db dyn HirDatabase,
         ctor: &Constructor<Self>,
         adt: hir_def::AdtId,
     ) -> Option<VariantId> {
@@ -126,7 +129,7 @@ impl<'p> MatchCheckCtx<'p> {
         &'a self,
         ty: &'a Ty,
         variant: VariantId,
-    ) -> impl Iterator<Item = (LocalFieldId, Ty)> + Captures<'a> + Captures<'p> {
+    ) -> impl Iterator<Item = (LocalFieldId, Ty)> + Captures<'a> + Captures<'db> {
         let (_, substs) = ty.as_adt().unwrap();
 
         let field_tys = self.db.field_types(variant);
@@ -139,8 +142,8 @@ impl<'p> MatchCheckCtx<'p> {
         })
     }
 
-    pub(crate) fn lower_pat(&self, pat: &Pat) -> DeconstructedPat<'p> {
-        let singleton = |pat: DeconstructedPat<'p>| vec![pat.at_index(0)];
+    pub(crate) fn lower_pat(&self, pat: &Pat) -> DeconstructedPat<'db> {
+        let singleton = |pat: DeconstructedPat<'db>| vec![pat.at_index(0)];
         let ctor;
         let mut fields: Vec<_>;
         let arity;
@@ -228,6 +231,11 @@ impl<'p> MatchCheckCtx<'p> {
                 fields = Vec::new();
                 arity = 0;
             }
+            PatKind::Never => {
+                ctor = Never;
+                fields = Vec::new();
+                arity = 0;
+            }
             PatKind::Or { pats } => {
                 ctor = Or;
                 fields = pats
@@ -238,11 +246,10 @@ impl<'p> MatchCheckCtx<'p> {
                 arity = pats.len();
             }
         }
-        let data = PatData { db: self.db };
-        DeconstructedPat::new(ctor, fields, arity, pat.ty.clone(), data)
+        DeconstructedPat::new(ctor, fields, arity, pat.ty.clone(), ())
     }
 
-    pub(crate) fn hoist_witness_pat(&self, pat: &WitnessPat<'p>) -> Pat {
+    pub(crate) fn hoist_witness_pat(&self, pat: &WitnessPat<'db>) -> Pat {
         let mut subpatterns = pat.iter_fields().map(|p| self.hoist_witness_pat(p));
         let kind = match pat.ctor() {
             &Bool(value) => PatKind::LiteralBool { value },
@@ -290,6 +297,7 @@ impl<'p> MatchCheckCtx<'p> {
             Slice(_) => unimplemented!(),
             &Str(void) => match void {},
             Wildcard | NonExhaustive | Hidden | PrivateUninhabited => PatKind::Wild,
+            Never => PatKind::Never,
             Missing | F32Range(..) | F64Range(..) | Opaque(..) | Or => {
                 never!("can't convert to pattern: {:?}", pat.ctor());
                 PatKind::Wild
@@ -299,13 +307,13 @@ impl<'p> MatchCheckCtx<'p> {
     }
 }
 
-impl<'p> PatCx for MatchCheckCtx<'p> {
+impl<'db> PatCx for MatchCheckCtx<'db> {
     type Error = ();
     type Ty = Ty;
     type VariantIdx = EnumVariantContiguousIndex;
     type StrLit = Void;
     type ArmData = ();
-    type PatData = PatData<'p>;
+    type PatData = ();
 
     fn is_exhaustive_patterns_feature_on(&self) -> bool {
         self.exhaustive_patterns
@@ -339,8 +347,8 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
             },
             Ref => 1,
             Slice(..) => unimplemented!(),
-            Bool(..) | IntRange(..) | F32Range(..) | F64Range(..) | Str(..) | Opaque(..)
-            | NonExhaustive | PrivateUninhabited | Hidden | Missing | Wildcard => 0,
+            Never | Bool(..) | IntRange(..) | F32Range(..) | F64Range(..) | Str(..)
+            | Opaque(..) | NonExhaustive | PrivateUninhabited | Hidden | Missing | Wildcard => 0,
             Or => {
                 never!("The `Or` constructor doesn't have a fixed arity");
                 0
@@ -402,8 +410,10 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
                 }
             },
             Slice(_) => unreachable!("Found a `Slice` constructor in match checking"),
-            Bool(..) | IntRange(..) | F32Range(..) | F64Range(..) | Str(..) | Opaque(..)
-            | NonExhaustive | PrivateUninhabited | Hidden | Missing | Wildcard => smallvec![],
+            Never | Bool(..) | IntRange(..) | F32Range(..) | F64Range(..) | Str(..)
+            | Opaque(..) | NonExhaustive | PrivateUninhabited | Hidden | Missing | Wildcard => {
+                smallvec![]
+            }
             Or => {
                 never!("called `Fields::wildcards` on an `Or` ctor");
                 smallvec![]
@@ -442,11 +452,8 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
                 if enum_data.variants.is_empty() && !is_declared_nonexhaustive {
                     ConstructorSet::NoConstructors
                 } else {
-                    let mut variants = FxHashMap::with_capacity_and_hasher(
-                        enum_data.variants.len(),
-                        Default::default(),
-                    );
-                    for (i, &(variant, _)) in enum_data.variants.iter().enumerate() {
+                    let mut variants = IndexVec::with_capacity(enum_data.variants.len());
+                    for &(variant, _) in enum_data.variants.iter() {
                         let is_uninhabited =
                             is_enum_variant_uninhabited_from(cx.db, variant, subst, cx.module);
                         let visibility = if is_uninhabited {
@@ -454,13 +461,10 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
                         } else {
                             VariantVisibility::Visible
                         };
-                        variants.insert(EnumVariantContiguousIndex(i), visibility);
+                        variants.push(visibility);
                     }
 
-                    ConstructorSet::Variants {
-                        variants: IdxContainer(variants),
-                        non_exhaustive: is_declared_nonexhaustive,
-                    }
+                    ConstructorSet::Variants { variants, non_exhaustive: is_declared_nonexhaustive }
                 }
             }
             TyKind::Adt(AdtId(hir_def::AdtId::UnionId(_)), _) => ConstructorSet::Union,
@@ -476,26 +480,27 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
 
     fn write_variant_name(
         f: &mut fmt::Formatter<'_>,
-        pat: &rustc_pattern_analysis::pat::DeconstructedPat<Self>,
+        _ctor: &Constructor<Self>,
+        _ty: &Self::Ty,
     ) -> fmt::Result {
-        let db = pat.data().db;
-        let variant =
-            pat.ty().as_adt().and_then(|(adt, _)| Self::variant_id_for_adt(db, pat.ctor(), adt));
-
-        if let Some(variant) = variant {
-            match variant {
-                VariantId::EnumVariantId(v) => {
-                    write!(f, "{}", db.enum_variant_data(v).name.display(db.upcast()))?;
-                }
-                VariantId::StructId(s) => {
-                    write!(f, "{}", db.struct_data(s).name.display(db.upcast()))?
-                }
-                VariantId::UnionId(u) => {
-                    write!(f, "{}", db.union_data(u).name.display(db.upcast()))?
-                }
-            }
-        }
-        Ok(())
+        write!(f, "<write_variant_name unsupported>")
+        // We lack the database here ...
+        // let variant = ty.as_adt().and_then(|(adt, _)| Self::variant_id_for_adt(db, ctor, adt));
+
+        // if let Some(variant) = variant {
+        //     match variant {
+        //         VariantId::EnumVariantId(v) => {
+        //             write!(f, "{}", db.enum_variant_data(v).name.display(db.upcast()))?;
+        //         }
+        //         VariantId::StructId(s) => {
+        //             write!(f, "{}", db.struct_data(s).name.display(db.upcast()))?
+        //         }
+        //         VariantId::UnionId(u) => {
+        //             write!(f, "{}", db.union_data(u).name.display(db.upcast()))?
+        //         }
+        //     }
+        // }
+        // Ok(())
     }
 
     fn bug(&self, fmt: fmt::Arguments<'_>) {
@@ -507,7 +512,7 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
     }
 }
 
-impl<'p> fmt::Debug for MatchCheckCtx<'p> {
+impl<'db> fmt::Debug for MatchCheckCtx<'db> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("MatchCheckCtx").finish()
     }