diff --git a/Cargo.lock b/Cargo.lock index 68ed32391b..a8e3dc338f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1432,9 +1432,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_abi" -version = "0.42.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ae52e2d5b08762c9464b541345f519b8719d57b643b73632bade43ecece9dc" +checksum = "b8709df2a746f055316bc0c62bd30948695a25e734863bf6e1f9755403e010ab" dependencies = [ "bitflags 2.4.2", "ra-ap-rustc_index", @@ -1443,9 +1443,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_index" -version = "0.42.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd7e10c7853fe79443d46e1d2d8ab09fe99926118e59653fb8b480d5045f126" +checksum = "9ad68bacffb87dcdbb23a3ce11261375078aaa06b85d348c49f39ffd5510dc20" dependencies = [ "arrayvec", "ra-ap-rustc_index_macros", @@ -1454,9 +1454,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_index_macros" -version = "0.42.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47f1d1c589be6c9a9e852fadee0e60329c0f862e87442ac2fe5adae30663cc76" +checksum = "8782aaf3a113837c533dfb1c45df91cd17e1fdd1d2f9a20c2e0d1976025c4f1f" dependencies = [ "proc-macro2", "quote", @@ -1466,9 +1466,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_lexer" -version = "0.42.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa852373a757b4c723bbdc96ced7f575cad68a1e266e45fee12bc4c69a482d80" +checksum = "aab683fc8579d09eb72033bd5dc9ba6d701aa9645b5fed087ef19af71184dff3" dependencies = [ "unicode-properties", "unicode-xid", @@ -1476,9 +1476,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_parse_format" -version = "0.42.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2afe3c49accd95a53ac4d72ae13bafc7d115bdd80c8cd56ab09e6fc68f482210" +checksum = "0bcf9ff5edbf784b67b8ad5e03a068f1300fcc24062c0d476b3018965135d933" dependencies = [ "ra-ap-rustc_index", "ra-ap-rustc_lexer", @@ -1486,9 +1486,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_pattern_analysis" -version = "0.42.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1253da23515d80c377a3998731e0ec3794997b62b989fd47db73efbde6a0bd7c" +checksum = "d63d1e1d5b2a13273cee1a10011147418f40e12b70f70578ce1dee0f1cafc334" dependencies = [ "ra-ap-rustc_index", "rustc-hash", diff --git a/Cargo.toml b/Cargo.toml index 0679522efd..e940741009 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,11 +84,11 @@ tt = { path = "./crates/tt", version = "0.0.0" } vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } vfs = { path = "./crates/vfs", version = "0.0.0" } -ra-ap-rustc_lexer = { version = "0.42.0", default-features = false } -ra-ap-rustc_parse_format = { version = "0.42.0", default-features = false } -ra-ap-rustc_index = { version = "0.42.0", default-features = false } -ra-ap-rustc_abi = { version = "0.42.0", default-features = false } -ra-ap-rustc_pattern_analysis = { version = "0.42.0", default-features = false } +ra-ap-rustc_lexer = { version = "0.44.0", default-features = false } +ra-ap-rustc_parse_format = { version = "0.44.0", default-features = false } +ra-ap-rustc_index = { version = "0.44.0", default-features = false } +ra-ap-rustc_abi = { version = "0.44.0", default-features = false } +ra-ap-rustc_pattern_analysis = { version = "0.44.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/crates/hir-ty/src/diagnostics/expr.rs b/crates/hir-ty/src/diagnostics/expr.rs index 67cfbc294d..b3128712dc 100644 --- a/crates/hir-ty/src/diagnostics/expr.rs +++ b/crates/hir-ty/src/diagnostics/expr.rs @@ -11,7 +11,7 @@ use hir_def::{ItemContainerId, Lookup}; use hir_expand::name; use itertools::Itertools; use rustc_hash::FxHashSet; -use rustc_pattern_analysis::usefulness::{compute_match_usefulness, ValidityConstraint}; +use rustc_pattern_analysis::usefulness::{compute_match_usefulness, PlaceValidity}; use syntax::{ast, AstNode}; use tracing::debug; use triomphe::Arc; @@ -238,7 +238,7 @@ impl ExprValidator { &cx, m_arms.as_slice(), scrut_ty.clone(), - ValidityConstraint::ValidOnly, + PlaceValidity::ValidOnly, None, ) { Ok(report) => report, @@ -286,7 +286,7 @@ impl ExprValidator { &cx, &[match_arm], ty.clone(), - ValidityConstraint::ValidOnly, + PlaceValidity::ValidOnly, None, ) { Ok(v) => v, diff --git a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index ca05842879..81ce51429c 100644 --- a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -8,7 +8,7 @@ use rustc_hash::FxHashMap; use rustc_pattern_analysis::{ constructor::{Constructor, ConstructorSet, VariantVisibility}, index::IdxContainer, - Captures, PrivateUninhabitedField, TypeCx, + Captures, PatCx, PrivateUninhabitedField, }; use smallvec::{smallvec, SmallVec}; use stdx::never; @@ -107,15 +107,17 @@ impl<'p> MatchCheckCtx<'p> { } pub(crate) fn lower_pat(&self, pat: &Pat) -> DeconstructedPat<'p> { - let singleton = |pat| vec![pat]; + let singleton = |pat: DeconstructedPat<'p>| vec![pat.at_index(0)]; let ctor; - let fields: Vec<_>; + let mut fields: Vec<_>; + let arity; match pat.kind.as_ref() { PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat), PatKind::Binding { subpattern: None, .. } | PatKind::Wild => { ctor = Wildcard; fields = Vec::new(); + arity = 0; } PatKind::Deref { subpattern } => { ctor = match pat.ty.kind(Interner) { @@ -128,23 +130,22 @@ impl<'p> MatchCheckCtx<'p> { } }; fields = singleton(self.lower_pat(subpattern)); + arity = 1; } PatKind::Leaf { subpatterns } | PatKind::Variant { subpatterns, .. } => { + fields = subpatterns + .iter() + .map(|pat| { + let idx: u32 = pat.field.into_raw().into(); + self.lower_pat(&pat.pattern).at_index(idx as usize) + }) + .collect(); match pat.ty.kind(Interner) { TyKind::Tuple(_, substs) => { ctor = Struct; - let mut wilds: Vec<_> = substs - .iter(Interner) - .map(|arg| arg.assert_ty_ref(Interner).clone()) - .map(DeconstructedPat::wildcard) - .collect(); - for pat in subpatterns { - let idx: u32 = pat.field.into_raw().into(); - wilds[idx as usize] = self.lower_pat(&pat.pattern); - } - fields = wilds + arity = substs.len(Interner); } - TyKind::Adt(adt, substs) if is_box(self.db, adt.0) => { + TyKind::Adt(adt, _) if is_box(self.db, adt.0) => { // The only legal patterns of type `Box` (outside `std`) are `_` and box // patterns. If we're here we can assume this is a box pattern. // FIXME(Nadrieril): A `Box` can in theory be matched either with `Box(_, @@ -157,16 +158,9 @@ impl<'p> MatchCheckCtx<'p> { // normally or through box-patterns. We'll have to figure out a proper // solution when we introduce generalized deref patterns. Also need to // prevent mixing of those two options. - let pat = - subpatterns.iter().find(|pat| pat.field.into_raw() == 0u32.into()); - let field = if let Some(pat) = pat { - self.lower_pat(&pat.pattern) - } else { - let ty = substs.at(Interner, 0).assert_ty_ref(Interner).clone(); - DeconstructedPat::wildcard(ty) - }; + fields.retain(|ipat| ipat.idx == 0); ctor = Struct; - fields = singleton(field); + arity = 1; } &TyKind::Adt(adt, _) => { ctor = match pat.kind.as_ref() { @@ -181,37 +175,33 @@ impl<'p> MatchCheckCtx<'p> { } }; let variant = Self::variant_id_for_adt(&ctor, adt.0).unwrap(); - // Fill a vec with wildcards, then place the fields we have at the right - // index. - let mut wilds: Vec<_> = self - .list_variant_fields(&pat.ty, variant) - .map(|(_, ty)| ty) - .map(DeconstructedPat::wildcard) - .collect(); - for pat in subpatterns { - let field_id: u32 = pat.field.into_raw().into(); - wilds[field_id as usize] = self.lower_pat(&pat.pattern); - } - fields = wilds; + arity = variant.variant_data(self.db.upcast()).fields().len(); } _ => { never!("pattern has unexpected type: pat: {:?}, ty: {:?}", pat, &pat.ty); ctor = Wildcard; - fields = Vec::new(); + fields.clear(); + arity = 0; } } } &PatKind::LiteralBool { value } => { ctor = Bool(value); fields = Vec::new(); + arity = 0; } PatKind::Or { pats } => { ctor = Or; - fields = pats.iter().map(|pat| self.lower_pat(pat)).collect(); + fields = pats + .iter() + .enumerate() + .map(|(i, pat)| self.lower_pat(pat).at_index(i)) + .collect(); + arity = pats.len(); } } let data = PatData { db: self.db }; - DeconstructedPat::new(ctor, fields, pat.ty.clone(), data) + DeconstructedPat::new(ctor, fields, arity, pat.ty.clone(), data) } pub(crate) fn hoist_witness_pat(&self, pat: &WitnessPat<'p>) -> Pat { @@ -271,7 +261,7 @@ impl<'p> MatchCheckCtx<'p> { } } -impl<'p> TypeCx for MatchCheckCtx<'p> { +impl<'p> PatCx for MatchCheckCtx<'p> { type Error = (); type Ty = Ty; type VariantIdx = EnumVariantId; @@ -453,7 +443,7 @@ impl<'p> TypeCx for MatchCheckCtx<'p> { let variant = pat.ty().as_adt().and_then(|(adt, _)| Self::variant_id_for_adt(pat.ctor(), adt)); - let db = pat.data().unwrap().db; + let db = pat.data().db; if let Some(variant) = variant { match variant { VariantId::EnumVariantId(v) => {