Skip to content

Commit bbb441e

Browse files
committed
Auto merge of #16778 - Nadrieril:update-pat-ana, r=lnicola
Update `rustc_pattern_analysis` to 0.42.0 There was an important API change in 0.41.0, and (hopefully) a fix for rust-lang/rust-analyzer#16774 in 0.42.0.
2 parents b1f6d56 + e31484c commit bbb441e

File tree

5 files changed

+75
-73
lines changed

5 files changed

+75
-73
lines changed

Cargo.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ tt = { path = "./crates/tt", version = "0.0.0" }
8484
vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" }
8585
vfs = { path = "./crates/vfs", version = "0.0.0" }
8686

87-
ra-ap-rustc_lexer = { version = "0.40.0", default-features = false }
88-
ra-ap-rustc_parse_format = { version = "0.40.0", default-features = false }
89-
ra-ap-rustc_index = { version = "0.40.0", default-features = false }
90-
ra-ap-rustc_abi = { version = "0.40.0", default-features = false }
91-
ra-ap-rustc_pattern_analysis = { version = "0.40.0", default-features = false }
87+
ra-ap-rustc_lexer = { version = "0.42.0", default-features = false }
88+
ra-ap-rustc_parse_format = { version = "0.42.0", default-features = false }
89+
ra-ap-rustc_index = { version = "0.42.0", default-features = false }
90+
ra-ap-rustc_abi = { version = "0.42.0", default-features = false }
91+
ra-ap-rustc_pattern_analysis = { version = "0.42.0", default-features = false }
9292

9393
# local crates that aren't published to crates.io. These should not have versions.
9494
sourcegen = { path = "./crates/sourcegen" }

crates/hir-ty/src/diagnostics/expr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ impl ExprValidator {
239239
m_arms.as_slice(),
240240
scrut_ty.clone(),
241241
ValidityConstraint::ValidOnly,
242+
None,
242243
) {
243244
Ok(report) => report,
244245
Err(()) => return,
@@ -283,6 +284,7 @@ impl ExprValidator {
283284
&[match_arm],
284285
ty.clone(),
285286
ValidityConstraint::ValidOnly,
287+
None,
286288
) {
287289
Ok(v) => v,
288290
Err(e) => {

crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_hash::FxHashMap;
88
use rustc_pattern_analysis::{
99
constructor::{Constructor, ConstructorSet, VariantVisibility},
1010
index::IdxContainer,
11-
Captures, TypeCx,
11+
Captures, PrivateUninhabitedField, TypeCx,
1212
};
1313
use smallvec::{smallvec, SmallVec};
1414
use stdx::never;
@@ -88,39 +88,21 @@ impl<'p> MatchCheckCtx<'p> {
8888
}
8989
}
9090

91-
// In the cases of either a `#[non_exhaustive]` field list or a non-public field, we hide
92-
// uninhabited fields in order not to reveal the uninhabitedness of the whole variant.
93-
// This lists the fields we keep along with their types.
94-
fn list_variant_nonhidden_fields<'a>(
91+
// This lists the fields of a variant along with their types.
92+
fn list_variant_fields<'a>(
9593
&'a self,
9694
ty: &'a Ty,
9795
variant: VariantId,
9896
) -> impl Iterator<Item = (LocalFieldId, Ty)> + Captures<'a> + Captures<'p> {
99-
let cx = self;
100-
let (adt, substs) = ty.as_adt().unwrap();
101-
102-
let adt_is_local = variant.module(cx.db.upcast()).krate() == cx.module.krate();
103-
104-
// Whether we must not match the fields of this variant exhaustively.
105-
let is_non_exhaustive =
106-
cx.db.attrs(variant.into()).by_key("non_exhaustive").exists() && !adt_is_local;
97+
let (_, substs) = ty.as_adt().unwrap();
10798

108-
let visibility = cx.db.field_visibilities(variant);
109-
let field_ty = cx.db.field_types(variant);
110-
let fields_len = variant.variant_data(cx.db.upcast()).fields().len() as u32;
99+
let field_tys = self.db.field_types(variant);
100+
let fields_len = variant.variant_data(self.db.upcast()).fields().len() as u32;
111101

112-
(0..fields_len).map(|idx| LocalFieldId::from_raw(idx.into())).filter_map(move |fid| {
113-
let ty = field_ty[fid].clone().substitute(Interner, substs);
114-
let ty = normalize(cx.db, cx.db.trait_environment_for_body(cx.body), ty);
115-
let is_visible = matches!(adt, hir_def::AdtId::EnumId(..))
116-
|| visibility[fid].is_visible_from(cx.db.upcast(), cx.module);
117-
let is_uninhabited = cx.is_uninhabited(&ty);
118-
119-
if is_uninhabited && (!is_visible || is_non_exhaustive) {
120-
None
121-
} else {
122-
Some((fid, ty))
123-
}
102+
(0..fields_len).map(|idx| LocalFieldId::from_raw(idx.into())).map(move |fid| {
103+
let ty = field_tys[fid].clone().substitute(Interner, substs);
104+
let ty = normalize(self.db, self.db.trait_environment_for_body(self.body), ty);
105+
(fid, ty)
124106
})
125107
}
126108

@@ -199,23 +181,16 @@ impl<'p> MatchCheckCtx<'p> {
199181
}
200182
};
201183
let variant = Self::variant_id_for_adt(&ctor, adt.0).unwrap();
202-
let fields_len = variant.variant_data(self.db.upcast()).fields().len();
203-
// For each field in the variant, we store the relevant index into `self.fields` if any.
204-
let mut field_id_to_id: Vec<Option<usize>> = vec![None; fields_len];
205-
let tys = self
206-
.list_variant_nonhidden_fields(&pat.ty, variant)
207-
.enumerate()
208-
.map(|(i, (fid, ty))| {
209-
let field_idx: u32 = fid.into_raw().into();
210-
field_id_to_id[field_idx as usize] = Some(i);
211-
ty
212-
});
213-
let mut wilds: Vec<_> = tys.map(DeconstructedPat::wildcard).collect();
184+
// Fill a vec with wildcards, then place the fields we have at the right
185+
// index.
186+
let mut wilds: Vec<_> = self
187+
.list_variant_fields(&pat.ty, variant)
188+
.map(|(_, ty)| ty)
189+
.map(DeconstructedPat::wildcard)
190+
.collect();
214191
for pat in subpatterns {
215-
let field_idx: u32 = pat.field.into_raw().into();
216-
if let Some(i) = field_id_to_id[field_idx as usize] {
217-
wilds[i] = self.lower_pat(&pat.pattern);
218-
}
192+
let field_id: u32 = pat.field.into_raw().into();
193+
wilds[field_id as usize] = self.lower_pat(&pat.pattern);
219194
}
220195
fields = wilds;
221196
}
@@ -263,7 +238,7 @@ impl<'p> MatchCheckCtx<'p> {
263238
TyKind::Adt(adt, substs) => {
264239
let variant = Self::variant_id_for_adt(pat.ctor(), adt.0).unwrap();
265240
let subpatterns = self
266-
.list_variant_nonhidden_fields(pat.ty(), variant)
241+
.list_variant_fields(pat.ty(), variant)
267242
.zip(subpatterns)
268243
.map(|((field, _ty), pattern)| FieldPat { field, pattern })
269244
.collect();
@@ -286,7 +261,7 @@ impl<'p> MatchCheckCtx<'p> {
286261
Ref => PatKind::Deref { subpattern: subpatterns.next().unwrap() },
287262
Slice(_) => unimplemented!(),
288263
&Str(void) => match void {},
289-
Wildcard | NonExhaustive | Hidden => PatKind::Wild,
264+
Wildcard | NonExhaustive | Hidden | PrivateUninhabited => PatKind::Wild,
290265
Missing | F32Range(..) | F64Range(..) | Opaque(..) | Or => {
291266
never!("can't convert to pattern: {:?}", pat.ctor());
292267
PatKind::Wild
@@ -326,7 +301,7 @@ impl<'p> TypeCx for MatchCheckCtx<'p> {
326301
1
327302
} else {
328303
let variant = Self::variant_id_for_adt(ctor, adt).unwrap();
329-
self.list_variant_nonhidden_fields(ty, variant).count()
304+
variant.variant_data(self.db.upcast()).fields().len()
330305
}
331306
}
332307
_ => {
@@ -337,7 +312,7 @@ impl<'p> TypeCx for MatchCheckCtx<'p> {
337312
Ref => 1,
338313
Slice(..) => unimplemented!(),
339314
Bool(..) | IntRange(..) | F32Range(..) | F64Range(..) | Str(..) | Opaque(..)
340-
| NonExhaustive | Hidden | Missing | Wildcard => 0,
315+
| NonExhaustive | PrivateUninhabited | Hidden | Missing | Wildcard => 0,
341316
Or => {
342317
never!("The `Or` constructor doesn't have a fixed arity");
343318
0
@@ -349,13 +324,13 @@ impl<'p> TypeCx for MatchCheckCtx<'p> {
349324
&'a self,
350325
ctor: &'a rustc_pattern_analysis::constructor::Constructor<Self>,
351326
ty: &'a Self::Ty,
352-
) -> impl ExactSizeIterator<Item = Self::Ty> + Captures<'a> {
353-
let single = |ty| smallvec![ty];
327+
) -> impl ExactSizeIterator<Item = (Self::Ty, PrivateUninhabitedField)> + Captures<'a> {
328+
let single = |ty| smallvec![(ty, PrivateUninhabitedField(false))];
354329
let tys: SmallVec<[_; 2]> = match ctor {
355330
Struct | Variant(_) | UnionField => match ty.kind(Interner) {
356331
TyKind::Tuple(_, substs) => {
357332
let tys = substs.iter(Interner).map(|ty| ty.assert_ty_ref(Interner));
358-
tys.cloned().collect()
333+
tys.cloned().map(|ty| (ty, PrivateUninhabitedField(false))).collect()
359334
}
360335
TyKind::Ref(.., rty) => single(rty.clone()),
361336
&TyKind::Adt(AdtId(adt), ref substs) => {
@@ -366,7 +341,27 @@ impl<'p> TypeCx for MatchCheckCtx<'p> {
366341
single(subst_ty)
367342
} else {
368343
let variant = Self::variant_id_for_adt(ctor, adt).unwrap();
369-
self.list_variant_nonhidden_fields(ty, variant).map(|(_, ty)| ty).collect()
344+
let (adt, _) = ty.as_adt().unwrap();
345+
346+
let adt_is_local =
347+
variant.module(self.db.upcast()).krate() == self.module.krate();
348+
// Whether we must not match the fields of this variant exhaustively.
349+
let is_non_exhaustive =
350+
self.db.attrs(variant.into()).by_key("non_exhaustive").exists()
351+
&& !adt_is_local;
352+
let visibilities = self.db.field_visibilities(variant);
353+
354+
self.list_variant_fields(ty, variant)
355+
.map(move |(fid, ty)| {
356+
let is_visible = matches!(adt, hir_def::AdtId::EnumId(..))
357+
|| visibilities[fid]
358+
.is_visible_from(self.db.upcast(), self.module);
359+
let is_uninhabited = self.is_uninhabited(&ty);
360+
let private_uninhabited =
361+
is_uninhabited && (!is_visible || is_non_exhaustive);
362+
(ty, PrivateUninhabitedField(private_uninhabited))
363+
})
364+
.collect()
370365
}
371366
}
372367
ty_kind => {
@@ -383,7 +378,7 @@ impl<'p> TypeCx for MatchCheckCtx<'p> {
383378
},
384379
Slice(_) => unreachable!("Found a `Slice` constructor in match checking"),
385380
Bool(..) | IntRange(..) | F32Range(..) | F64Range(..) | Str(..) | Opaque(..)
386-
| NonExhaustive | Hidden | Missing | Wildcard => smallvec![],
381+
| NonExhaustive | PrivateUninhabited | Hidden | Missing | Wildcard => smallvec![],
387382
Or => {
388383
never!("called `Fields::wildcards` on an `Or` ctor");
389384
smallvec![]
@@ -478,6 +473,11 @@ impl<'p> TypeCx for MatchCheckCtx<'p> {
478473
fn bug(&self, fmt: fmt::Arguments<'_>) {
479474
debug!("{}", fmt)
480475
}
476+
477+
fn complexity_exceeded(&self) -> Result<(), Self::Error> {
478+
// FIXME(Nadrieril): make use of the complexity counter.
479+
Err(())
480+
}
481481
}
482482

483483
impl<'p> fmt::Debug for MatchCheckCtx<'p> {

crates/hir-ty/src/layout.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Compute the binary representation of a type
22
3-
use std::fmt;
3+
use std::{borrow::Cow, fmt};
44

55
use base_db::salsa::Cycle;
66
use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy};
@@ -114,8 +114,8 @@ struct LayoutCx<'a> {
114114
impl<'a> LayoutCalculator for LayoutCx<'a> {
115115
type TargetDataLayoutRef = &'a TargetDataLayout;
116116

117-
fn delayed_bug(&self, txt: String) {
118-
never!("{}", txt);
117+
fn delayed_bug(&self, txt: impl Into<Cow<'static, str>>) {
118+
never!("{}", txt.into());
119119
}
120120

121121
fn current_data_layout(&self) -> &'a TargetDataLayout {

0 commit comments

Comments
 (0)