diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs | 24 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/pattern/usefulness.rs | 20 |
3 files changed, 24 insertions, 24 deletions
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index 4d17e8c9a..88018b5d9 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -373,12 +373,12 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
373 | let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) = | 373 | let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) = |
374 | db.body_with_source_map(self.owner); | 374 | db.body_with_source_map(self.owner); |
375 | 375 | ||
376 | let match_expr_ty = if infer.type_of_expr[match_expr].is_unknown() { | 376 | let _match_expr_ty = if infer.type_of_expr[match_expr].is_unknown() { |
377 | return; | 377 | return; |
378 | } else { | 378 | } else { |
379 | &infer.type_of_expr[match_expr] | 379 | &infer.type_of_expr[match_expr] |
380 | }; | 380 | }; |
381 | // eprintln!("ExprValidator::validate_match2({:?})", match_expr_ty.kind(&Interner)); | 381 | // eprintln!("ExprValidator::validate_match2({:?})", _match_expr_ty.kind(&Interner)); |
382 | 382 | ||
383 | let pattern_arena = usefulness::PatternArena::clone_from(&body.pats); | 383 | let pattern_arena = usefulness::PatternArena::clone_from(&body.pats); |
384 | let cx = usefulness::MatchCheckCtx { | 384 | let cx = usefulness::MatchCheckCtx { |
diff --git a/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs b/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs index 2f3555205..d41b95d2f 100644 --- a/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs +++ b/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs | |||
@@ -143,7 +143,7 @@ impl Constructor { | |||
143 | /// matrix, unless all of them are. | 143 | /// matrix, unless all of them are. |
144 | pub(super) fn split<'a>( | 144 | pub(super) fn split<'a>( |
145 | &self, | 145 | &self, |
146 | pcx: &PatCtxt<'_>, | 146 | pcx: PatCtxt<'_>, |
147 | ctors: impl Iterator<Item = &'a Constructor> + Clone, | 147 | ctors: impl Iterator<Item = &'a Constructor> + Clone, |
148 | ) -> SmallVec<[Self; 1]> { | 148 | ) -> SmallVec<[Self; 1]> { |
149 | match self { | 149 | match self { |
@@ -166,7 +166,7 @@ impl Constructor { | |||
166 | /// this checks for inclusion. | 166 | /// this checks for inclusion. |
167 | // We inline because this has a single call site in `Matrix::specialize_constructor`. | 167 | // We inline because this has a single call site in `Matrix::specialize_constructor`. |
168 | #[inline] | 168 | #[inline] |
169 | pub(super) fn is_covered_by(&self, pcx: &PatCtxt<'_>, other: &Self) -> bool { | 169 | pub(super) fn is_covered_by(&self, pcx: PatCtxt<'_>, other: &Self) -> bool { |
170 | // This must be kept in sync with `is_covered_by_any`. | 170 | // This must be kept in sync with `is_covered_by_any`. |
171 | match (self, other) { | 171 | match (self, other) { |
172 | // Wildcards cover anything | 172 | // Wildcards cover anything |
@@ -188,7 +188,7 @@ impl Constructor { | |||
188 | /// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is | 188 | /// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is |
189 | /// assumed to be built from `matrix.head_ctors()` with wildcards filtered out, and `self` is | 189 | /// assumed to be built from `matrix.head_ctors()` with wildcards filtered out, and `self` is |
190 | /// assumed to have been split from a wildcard. | 190 | /// assumed to have been split from a wildcard. |
191 | fn is_covered_by_any(&self, pcx: &PatCtxt<'_>, used_ctors: &[Constructor]) -> bool { | 191 | fn is_covered_by_any(&self, pcx: PatCtxt<'_>, used_ctors: &[Constructor]) -> bool { |
192 | if used_ctors.is_empty() { | 192 | if used_ctors.is_empty() { |
193 | return false; | 193 | return false; |
194 | } | 194 | } |
@@ -236,7 +236,7 @@ pub(super) struct SplitWildcard { | |||
236 | } | 236 | } |
237 | 237 | ||
238 | impl SplitWildcard { | 238 | impl SplitWildcard { |
239 | pub(super) fn new(pcx: &PatCtxt<'_>) -> Self { | 239 | pub(super) fn new(pcx: PatCtxt<'_>) -> Self { |
240 | // let cx = pcx.cx; | 240 | // let cx = pcx.cx; |
241 | // let make_range = |start, end| IntRange(todo!()); | 241 | // let make_range = |start, end| IntRange(todo!()); |
242 | 242 | ||
@@ -260,7 +260,7 @@ impl SplitWildcard { | |||
260 | /// do what you want. | 260 | /// do what you want. |
261 | pub(super) fn split<'a>( | 261 | pub(super) fn split<'a>( |
262 | &mut self, | 262 | &mut self, |
263 | pcx: &PatCtxt<'_>, | 263 | pcx: PatCtxt<'_>, |
264 | ctors: impl Iterator<Item = &'a Constructor> + Clone, | 264 | ctors: impl Iterator<Item = &'a Constructor> + Clone, |
265 | ) { | 265 | ) { |
266 | // Since `all_ctors` never contains wildcards, this won't recurse further. | 266 | // Since `all_ctors` never contains wildcards, this won't recurse further. |
@@ -270,21 +270,21 @@ impl SplitWildcard { | |||
270 | } | 270 | } |
271 | 271 | ||
272 | /// Whether there are any value constructors for this type that are not present in the matrix. | 272 | /// Whether there are any value constructors for this type that are not present in the matrix. |
273 | fn any_missing(&self, pcx: &PatCtxt<'_>) -> bool { | 273 | fn any_missing(&self, pcx: PatCtxt<'_>) -> bool { |
274 | self.iter_missing(pcx).next().is_some() | 274 | self.iter_missing(pcx).next().is_some() |
275 | } | 275 | } |
276 | 276 | ||
277 | /// Iterate over the constructors for this type that are not present in the matrix. | 277 | /// Iterate over the constructors for this type that are not present in the matrix. |
278 | pub(super) fn iter_missing<'a>( | 278 | pub(super) fn iter_missing<'a>( |
279 | &'a self, | 279 | &'a self, |
280 | pcx: &'a PatCtxt<'_>, | 280 | pcx: PatCtxt<'a>, |
281 | ) -> impl Iterator<Item = &'a Constructor> { | 281 | ) -> impl Iterator<Item = &'a Constructor> { |
282 | self.all_ctors.iter().filter(move |ctor| !ctor.is_covered_by_any(pcx, &self.matrix_ctors)) | 282 | self.all_ctors.iter().filter(move |ctor| !ctor.is_covered_by_any(pcx, &self.matrix_ctors)) |
283 | } | 283 | } |
284 | 284 | ||
285 | /// Return the set of constructors resulting from splitting the wildcard. As explained at the | 285 | /// Return the set of constructors resulting from splitting the wildcard. As explained at the |
286 | /// top of the file, if any constructors are missing we can ignore the present ones. | 286 | /// top of the file, if any constructors are missing we can ignore the present ones. |
287 | fn into_ctors(self, pcx: &PatCtxt<'_>) -> SmallVec<[Constructor; 1]> { | 287 | fn into_ctors(self, pcx: PatCtxt<'_>) -> SmallVec<[Constructor; 1]> { |
288 | if self.any_missing(pcx) { | 288 | if self.any_missing(pcx) { |
289 | // Some constructors are missing, thus we can specialize with the special `Missing` | 289 | // Some constructors are missing, thus we can specialize with the special `Missing` |
290 | // constructor, which stands for those constructors that are not seen in the matrix, | 290 | // constructor, which stands for those constructors that are not seen in the matrix, |
@@ -313,7 +313,7 @@ impl SplitWildcard { | |||
313 | // | 313 | // |
314 | // The exception is: if we are at the top-level, for example in an empty match, we | 314 | // The exception is: if we are at the top-level, for example in an empty match, we |
315 | // sometimes prefer reporting the list of constructors instead of just `_`. | 315 | // sometimes prefer reporting the list of constructors instead of just `_`. |
316 | let report_when_all_missing = pcx.is_top_level && !IntRange::is_integral(&pcx.ty); | 316 | let report_when_all_missing = pcx.is_top_level && !IntRange::is_integral(pcx.ty); |
317 | let ctor = if !self.matrix_ctors.is_empty() || report_when_all_missing { | 317 | let ctor = if !self.matrix_ctors.is_empty() || report_when_all_missing { |
318 | Missing | 318 | Missing |
319 | } else { | 319 | } else { |
@@ -381,8 +381,8 @@ impl Fields { | |||
381 | Fields::Vec(pats) | 381 | Fields::Vec(pats) |
382 | } | 382 | } |
383 | 383 | ||
384 | pub(crate) fn wildcards(pcx: &PatCtxt<'_>, constructor: &Constructor) -> Self { | 384 | pub(crate) fn wildcards(pcx: PatCtxt<'_>, constructor: &Constructor) -> Self { |
385 | let ty = &pcx.ty; | 385 | let ty = pcx.ty; |
386 | let cx = pcx.cx; | 386 | let cx = pcx.cx; |
387 | let wildcard_from_ty = |ty| cx.alloc_pat(Pat::Wild, ty); | 387 | let wildcard_from_ty = |ty| cx.alloc_pat(Pat::Wild, ty); |
388 | 388 | ||
@@ -446,7 +446,7 @@ impl Fields { | |||
446 | /// `ty`: `Option<bool>` | 446 | /// `ty`: `Option<bool>` |
447 | /// `self`: `[false]` | 447 | /// `self`: `[false]` |
448 | /// returns `Some(false)` | 448 | /// returns `Some(false)` |
449 | pub(super) fn apply(self, pcx: &PatCtxt<'_>, ctor: &Constructor) -> Pat { | 449 | pub(super) fn apply(self, pcx: PatCtxt<'_>, ctor: &Constructor) -> Pat { |
450 | let subpatterns_and_indices = self.patterns_and_indices(); | 450 | let subpatterns_and_indices = self.patterns_and_indices(); |
451 | let mut subpatterns = subpatterns_and_indices.iter().map(|&(_, p)| p); | 451 | let mut subpatterns = subpatterns_and_indices.iter().map(|&(_, p)| p); |
452 | 452 | ||
diff --git a/crates/hir_ty/src/diagnostics/pattern/usefulness.rs b/crates/hir_ty/src/diagnostics/pattern/usefulness.rs index 89e6c6593..7d9ab849b 100644 --- a/crates/hir_ty/src/diagnostics/pattern/usefulness.rs +++ b/crates/hir_ty/src/diagnostics/pattern/usefulness.rs | |||
@@ -51,11 +51,11 @@ impl<'a> MatchCheckCtx<'a> { | |||
51 | } | 51 | } |
52 | } | 52 | } |
53 | 53 | ||
54 | #[derive(Clone)] | 54 | #[derive(Copy, Clone)] |
55 | pub(super) struct PatCtxt<'a> { | 55 | pub(super) struct PatCtxt<'a> { |
56 | pub(super) cx: &'a MatchCheckCtx<'a>, | 56 | pub(super) cx: &'a MatchCheckCtx<'a>, |
57 | /// Type of the current column under investigation. | 57 | /// Type of the current column under investigation. |
58 | pub(super) ty: Ty, | 58 | pub(super) ty: &'a Ty, |
59 | /// Whether the current pattern is the whole pattern as found in a match arm, or if it's a | 59 | /// Whether the current pattern is the whole pattern as found in a match arm, or if it's a |
60 | /// subpattern. | 60 | /// subpattern. |
61 | pub(super) is_top_level: bool, | 61 | pub(super) is_top_level: bool, |
@@ -223,7 +223,7 @@ impl Matrix { | |||
223 | /// This computes `S(constructor, self)`. See top of the file for explanations. | 223 | /// This computes `S(constructor, self)`. See top of the file for explanations. |
224 | fn specialize_constructor( | 224 | fn specialize_constructor( |
225 | &self, | 225 | &self, |
226 | pcx: &PatCtxt<'_>, | 226 | pcx: PatCtxt<'_>, |
227 | ctor: &Constructor, | 227 | ctor: &Constructor, |
228 | ctor_wild_subpatterns: &Fields, | 228 | ctor_wild_subpatterns: &Fields, |
229 | ) -> Matrix { | 229 | ) -> Matrix { |
@@ -447,7 +447,7 @@ impl Usefulness { | |||
447 | /// with the results of specializing with the other constructors. | 447 | /// with the results of specializing with the other constructors. |
448 | fn apply_constructor( | 448 | fn apply_constructor( |
449 | self, | 449 | self, |
450 | pcx: &PatCtxt<'_>, | 450 | pcx: PatCtxt<'_>, |
451 | matrix: &Matrix, | 451 | matrix: &Matrix, |
452 | ctor: &Constructor, | 452 | ctor: &Constructor, |
453 | ctor_wild_subpatterns: &Fields, | 453 | ctor_wild_subpatterns: &Fields, |
@@ -555,7 +555,7 @@ impl Witness { | |||
555 | /// pats: [(false, "foo"), 42] => X { a: (false, "foo"), b: 42 } | 555 | /// pats: [(false, "foo"), 42] => X { a: (false, "foo"), b: 42 } |
556 | fn apply_constructor( | 556 | fn apply_constructor( |
557 | mut self, | 557 | mut self, |
558 | pcx: &PatCtxt<'_>, | 558 | pcx: PatCtxt<'_>, |
559 | ctor: &Constructor, | 559 | ctor: &Constructor, |
560 | ctor_wild_subpatterns: &Fields, | 560 | ctor_wild_subpatterns: &Fields, |
561 | ) -> Self { | 561 | ) -> Self { |
@@ -623,7 +623,7 @@ fn is_useful( | |||
623 | // FIXME(Nadrieril): Hack to work around type normalization issues (see rust-lang/rust#72476). | 623 | // FIXME(Nadrieril): Hack to work around type normalization issues (see rust-lang/rust#72476). |
624 | // TODO(iDawer): ty.strip_references() ? | 624 | // TODO(iDawer): ty.strip_references() ? |
625 | let ty = matrix.heads().next().map_or(cx.type_of(v.head()), |r| cx.type_of(r)); | 625 | let ty = matrix.heads().next().map_or(cx.type_of(v.head()), |r| cx.type_of(r)); |
626 | let pcx = PatCtxt { cx, ty, is_top_level }; | 626 | let pcx = PatCtxt { cx, ty: &ty, is_top_level }; |
627 | 627 | ||
628 | // If the first pattern is an or-pattern, expand it. | 628 | // If the first pattern is an or-pattern, expand it. |
629 | let ret = if v.head().is_or_pat(cx) { | 629 | let ret = if v.head().is_or_pat(cx) { |
@@ -657,20 +657,20 @@ fn is_useful( | |||
657 | // } | 657 | // } |
658 | 658 | ||
659 | // We split the head constructor of `v`. | 659 | // We split the head constructor of `v`. |
660 | let split_ctors = v_ctor.split(&pcx, matrix.head_ctors(cx)); | 660 | let split_ctors = v_ctor.split(pcx, matrix.head_ctors(cx)); |
661 | // For each constructor, we compute whether there's a value that starts with it that would | 661 | // For each constructor, we compute whether there's a value that starts with it that would |
662 | // witness the usefulness of `v`. | 662 | // witness the usefulness of `v`. |
663 | let start_matrix = matrix; | 663 | let start_matrix = matrix; |
664 | let usefulnesses = split_ctors.into_iter().map(|ctor| { | 664 | let usefulnesses = split_ctors.into_iter().map(|ctor| { |
665 | // debug!("specialize({:?})", ctor); | 665 | // debug!("specialize({:?})", ctor); |
666 | // We cache the result of `Fields::wildcards` because it is used a lot. | 666 | // We cache the result of `Fields::wildcards` because it is used a lot. |
667 | let ctor_wild_subpatterns = Fields::wildcards(&pcx, &ctor); | 667 | let ctor_wild_subpatterns = Fields::wildcards(pcx, &ctor); |
668 | let spec_matrix = | 668 | let spec_matrix = |
669 | start_matrix.specialize_constructor(&pcx, &ctor, &ctor_wild_subpatterns); | 669 | start_matrix.specialize_constructor(pcx, &ctor, &ctor_wild_subpatterns); |
670 | let v = v.pop_head_constructor(&ctor_wild_subpatterns, cx); | 670 | let v = v.pop_head_constructor(&ctor_wild_subpatterns, cx); |
671 | let usefulness = | 671 | let usefulness = |
672 | is_useful(cx, &spec_matrix, &v, witness_preference, is_under_guard, false); | 672 | is_useful(cx, &spec_matrix, &v, witness_preference, is_under_guard, false); |
673 | usefulness.apply_constructor(&pcx, start_matrix, &ctor, &ctor_wild_subpatterns) | 673 | usefulness.apply_constructor(pcx, start_matrix, &ctor, &ctor_wild_subpatterns) |
674 | }); | 674 | }); |
675 | Usefulness::merge(witness_preference, usefulnesses) | 675 | Usefulness::merge(witness_preference, usefulnesses) |
676 | }; | 676 | }; |