@@ -4,10 +4,9 @@ use std::fmt;
4
4
5
5
use hir_def:: { DefWithBodyId , EnumId , EnumVariantId , HasModule , LocalFieldId , ModuleId , VariantId } ;
6
6
use once_cell:: unsync:: Lazy ;
7
- use rustc_hash :: FxHashMap ;
7
+ use rustc_index :: IndexVec ;
8
8
use rustc_pattern_analysis:: {
9
9
constructor:: { Constructor , ConstructorSet , VariantVisibility } ,
10
- index:: IdxContainer ,
11
10
usefulness:: { compute_match_usefulness, PlaceValidity , UsefulnessReport } ,
12
11
Captures , PatCx , PrivateUninhabitedField ,
13
12
} ;
@@ -26,10 +25,10 @@ use super::{is_box, FieldPat, Pat, PatKind};
26
25
use Constructor :: * ;
27
26
28
27
// Re-export r-a-specific versions of all these types.
29
- pub ( crate ) type DeconstructedPat < ' p > =
30
- rustc_pattern_analysis:: pat:: DeconstructedPat < MatchCheckCtx < ' p > > ;
31
- pub ( crate ) type MatchArm < ' p > = rustc_pattern_analysis:: MatchArm < ' p , MatchCheckCtx < ' p > > ;
32
- pub ( crate ) type WitnessPat < ' p > = rustc_pattern_analysis:: pat:: WitnessPat < MatchCheckCtx < ' p > > ;
28
+ pub ( crate ) type DeconstructedPat < ' db > =
29
+ rustc_pattern_analysis:: pat:: DeconstructedPat < MatchCheckCtx < ' db > > ;
30
+ pub ( crate ) type MatchArm < ' db > = rustc_pattern_analysis:: MatchArm < ' db , MatchCheckCtx < ' db > > ;
31
+ pub ( crate ) type WitnessPat < ' db > = rustc_pattern_analysis:: pat:: WitnessPat < MatchCheckCtx < ' db > > ;
33
32
34
33
/// [Constructor] uses this in unimplemented variants.
35
34
/// It allows porting match expressions from upstream algorithm without losing semantics.
@@ -54,23 +53,27 @@ impl EnumVariantContiguousIndex {
54
53
}
55
54
}
56
55
56
+ impl rustc_index:: Idx for EnumVariantContiguousIndex {
57
+ fn new ( idx : usize ) -> Self {
58
+ EnumVariantContiguousIndex ( idx)
59
+ }
60
+
61
+ fn index ( self ) -> usize {
62
+ self . 0
63
+ }
64
+ }
65
+
57
66
#[ derive( Clone ) ]
58
- pub ( crate ) struct MatchCheckCtx < ' p > {
67
+ pub ( crate ) struct MatchCheckCtx < ' db > {
59
68
module : ModuleId ,
60
69
body : DefWithBodyId ,
61
- pub ( crate ) db : & ' p dyn HirDatabase ,
70
+ pub ( crate ) db : & ' db dyn HirDatabase ,
62
71
exhaustive_patterns : bool ,
63
72
min_exhaustive_patterns : bool ,
64
73
}
65
74
66
- #[ derive( Clone ) ]
67
- pub ( crate ) struct PatData < ' p > {
68
- /// Keep db around so that we can print variant names in `Debug`.
69
- pub ( crate ) db : & ' p dyn HirDatabase ,
70
- }
71
-
72
- impl < ' p > MatchCheckCtx < ' p > {
73
- pub ( crate ) fn new ( module : ModuleId , body : DefWithBodyId , db : & ' p dyn HirDatabase ) -> Self {
75
+ impl < ' db > MatchCheckCtx < ' db > {
76
+ pub ( crate ) fn new ( module : ModuleId , body : DefWithBodyId , db : & ' db dyn HirDatabase ) -> Self {
74
77
let def_map = db. crate_def_map ( module. krate ( ) ) ;
75
78
let exhaustive_patterns = def_map. is_unstable_feature_enabled ( "exhaustive_patterns" ) ;
76
79
let min_exhaustive_patterns =
@@ -80,9 +83,9 @@ impl<'p> MatchCheckCtx<'p> {
80
83
81
84
pub ( crate ) fn compute_match_usefulness (
82
85
& self ,
83
- arms : & [ MatchArm < ' p > ] ,
86
+ arms : & [ MatchArm < ' db > ] ,
84
87
scrut_ty : Ty ,
85
- ) -> Result < UsefulnessReport < ' p , Self > , ( ) > {
88
+ ) -> Result < UsefulnessReport < ' db , Self > , ( ) > {
86
89
// FIXME: Determine place validity correctly. For now, err on the safe side.
87
90
let place_validity = PlaceValidity :: MaybeInvalid ;
88
91
// Measured to take ~100ms on modern hardware.
@@ -101,7 +104,7 @@ impl<'p> MatchCheckCtx<'p> {
101
104
}
102
105
103
106
fn variant_id_for_adt (
104
- db : & ' p dyn HirDatabase ,
107
+ db : & ' db dyn HirDatabase ,
105
108
ctor : & Constructor < Self > ,
106
109
adt : hir_def:: AdtId ,
107
110
) -> Option < VariantId > {
@@ -126,7 +129,7 @@ impl<'p> MatchCheckCtx<'p> {
126
129
& ' a self ,
127
130
ty : & ' a Ty ,
128
131
variant : VariantId ,
129
- ) -> impl Iterator < Item = ( LocalFieldId , Ty ) > + Captures < ' a > + Captures < ' p > {
132
+ ) -> impl Iterator < Item = ( LocalFieldId , Ty ) > + Captures < ' a > + Captures < ' db > {
130
133
let ( _, substs) = ty. as_adt ( ) . unwrap ( ) ;
131
134
132
135
let field_tys = self . db . field_types ( variant) ;
@@ -139,8 +142,8 @@ impl<'p> MatchCheckCtx<'p> {
139
142
} )
140
143
}
141
144
142
- pub ( crate ) fn lower_pat ( & self , pat : & Pat ) -> DeconstructedPat < ' p > {
143
- let singleton = |pat : DeconstructedPat < ' p > | vec ! [ pat. at_index( 0 ) ] ;
145
+ pub ( crate ) fn lower_pat ( & self , pat : & Pat ) -> DeconstructedPat < ' db > {
146
+ let singleton = |pat : DeconstructedPat < ' db > | vec ! [ pat. at_index( 0 ) ] ;
144
147
let ctor;
145
148
let mut fields: Vec < _ > ;
146
149
let arity;
@@ -228,6 +231,11 @@ impl<'p> MatchCheckCtx<'p> {
228
231
fields = Vec :: new ( ) ;
229
232
arity = 0 ;
230
233
}
234
+ PatKind :: Never => {
235
+ ctor = Never ;
236
+ fields = Vec :: new ( ) ;
237
+ arity = 0 ;
238
+ }
231
239
PatKind :: Or { pats } => {
232
240
ctor = Or ;
233
241
fields = pats
@@ -238,11 +246,10 @@ impl<'p> MatchCheckCtx<'p> {
238
246
arity = pats. len ( ) ;
239
247
}
240
248
}
241
- let data = PatData { db : self . db } ;
242
- DeconstructedPat :: new ( ctor, fields, arity, pat. ty . clone ( ) , data)
249
+ DeconstructedPat :: new ( ctor, fields, arity, pat. ty . clone ( ) , ( ) )
243
250
}
244
251
245
- pub ( crate ) fn hoist_witness_pat ( & self , pat : & WitnessPat < ' p > ) -> Pat {
252
+ pub ( crate ) fn hoist_witness_pat ( & self , pat : & WitnessPat < ' db > ) -> Pat {
246
253
let mut subpatterns = pat. iter_fields ( ) . map ( |p| self . hoist_witness_pat ( p) ) ;
247
254
let kind = match pat. ctor ( ) {
248
255
& Bool ( value) => PatKind :: LiteralBool { value } ,
@@ -290,6 +297,7 @@ impl<'p> MatchCheckCtx<'p> {
290
297
Slice ( _) => unimplemented ! ( ) ,
291
298
& Str ( void) => match void { } ,
292
299
Wildcard | NonExhaustive | Hidden | PrivateUninhabited => PatKind :: Wild ,
300
+ Never => PatKind :: Never ,
293
301
Missing | F32Range ( ..) | F64Range ( ..) | Opaque ( ..) | Or => {
294
302
never ! ( "can't convert to pattern: {:?}" , pat. ctor( ) ) ;
295
303
PatKind :: Wild
@@ -299,13 +307,13 @@ impl<'p> MatchCheckCtx<'p> {
299
307
}
300
308
}
301
309
302
- impl < ' p > PatCx for MatchCheckCtx < ' p > {
310
+ impl < ' db > PatCx for MatchCheckCtx < ' db > {
303
311
type Error = ( ) ;
304
312
type Ty = Ty ;
305
313
type VariantIdx = EnumVariantContiguousIndex ;
306
314
type StrLit = Void ;
307
315
type ArmData = ( ) ;
308
- type PatData = PatData < ' p > ;
316
+ type PatData = ( ) ;
309
317
310
318
fn is_exhaustive_patterns_feature_on ( & self ) -> bool {
311
319
self . exhaustive_patterns
@@ -339,8 +347,8 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
339
347
} ,
340
348
Ref => 1 ,
341
349
Slice ( ..) => unimplemented ! ( ) ,
342
- Bool ( ..) | IntRange ( ..) | F32Range ( ..) | F64Range ( ..) | Str ( .. ) | Opaque ( ..)
343
- | NonExhaustive | PrivateUninhabited | Hidden | Missing | Wildcard => 0 ,
350
+ Never | Bool ( ..) | IntRange ( ..) | F32Range ( ..) | F64Range ( ..) | Str ( ..)
351
+ | Opaque ( .. ) | NonExhaustive | PrivateUninhabited | Hidden | Missing | Wildcard => 0 ,
344
352
Or => {
345
353
never ! ( "The `Or` constructor doesn't have a fixed arity" ) ;
346
354
0
@@ -402,8 +410,10 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
402
410
}
403
411
} ,
404
412
Slice ( _) => unreachable ! ( "Found a `Slice` constructor in match checking" ) ,
405
- Bool ( ..) | IntRange ( ..) | F32Range ( ..) | F64Range ( ..) | Str ( ..) | Opaque ( ..)
406
- | NonExhaustive | PrivateUninhabited | Hidden | Missing | Wildcard => smallvec ! [ ] ,
413
+ Never | Bool ( ..) | IntRange ( ..) | F32Range ( ..) | F64Range ( ..) | Str ( ..)
414
+ | Opaque ( ..) | NonExhaustive | PrivateUninhabited | Hidden | Missing | Wildcard => {
415
+ smallvec ! [ ]
416
+ }
407
417
Or => {
408
418
never ! ( "called `Fields::wildcards` on an `Or` ctor" ) ;
409
419
smallvec ! [ ]
@@ -442,25 +452,19 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
442
452
if enum_data. variants . is_empty ( ) && !is_declared_nonexhaustive {
443
453
ConstructorSet :: NoConstructors
444
454
} else {
445
- let mut variants = FxHashMap :: with_capacity_and_hasher (
446
- enum_data. variants . len ( ) ,
447
- Default :: default ( ) ,
448
- ) ;
449
- for ( i, & ( variant, _) ) in enum_data. variants . iter ( ) . enumerate ( ) {
455
+ let mut variants = IndexVec :: with_capacity ( enum_data. variants . len ( ) ) ;
456
+ for & ( variant, _) in enum_data. variants . iter ( ) {
450
457
let is_uninhabited =
451
458
is_enum_variant_uninhabited_from ( cx. db , variant, subst, cx. module ) ;
452
459
let visibility = if is_uninhabited {
453
460
VariantVisibility :: Empty
454
461
} else {
455
462
VariantVisibility :: Visible
456
463
} ;
457
- variants. insert ( EnumVariantContiguousIndex ( i ) , visibility) ;
464
+ variants. push ( visibility) ;
458
465
}
459
466
460
- ConstructorSet :: Variants {
461
- variants : IdxContainer ( variants) ,
462
- non_exhaustive : is_declared_nonexhaustive,
463
- }
467
+ ConstructorSet :: Variants { variants, non_exhaustive : is_declared_nonexhaustive }
464
468
}
465
469
}
466
470
TyKind :: Adt ( AdtId ( hir_def:: AdtId :: UnionId ( _) ) , _) => ConstructorSet :: Union ,
@@ -476,26 +480,27 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
476
480
477
481
fn write_variant_name (
478
482
f : & mut fmt:: Formatter < ' _ > ,
479
- pat : & rustc_pattern_analysis:: pat:: DeconstructedPat < Self > ,
483
+ _ctor : & Constructor < Self > ,
484
+ _ty : & Self :: Ty ,
480
485
) -> fmt:: Result {
481
- let db = pat . data ( ) . db ;
482
- let variant =
483
- pat . ty ( ) . as_adt ( ) . and_then ( |( adt, _) | Self :: variant_id_for_adt ( db, pat . ctor ( ) , adt) ) ;
484
-
485
- if let Some ( variant) = variant {
486
- match variant {
487
- VariantId :: EnumVariantId ( v) => {
488
- write ! ( f, "{}" , db. enum_variant_data( v) . name. display( db. upcast( ) ) ) ?;
489
- }
490
- VariantId :: StructId ( s) => {
491
- write ! ( f, "{}" , db. struct_data( s) . name. display( db. upcast( ) ) ) ?
492
- }
493
- VariantId :: UnionId ( u) => {
494
- write ! ( f, "{}" , db. union_data( u) . name. display( db. upcast( ) ) ) ?
495
- }
496
- }
497
- }
498
- Ok ( ( ) )
486
+ write ! ( f , "<write_variant_name unsupported>" )
487
+ // We lack the database here ...
488
+ // let variant = ty .as_adt().and_then(|(adt, _)| Self::variant_id_for_adt(db, ctor, adt));
489
+
490
+ // if let Some(variant) = variant {
491
+ // match variant {
492
+ // VariantId::EnumVariantId(v) => {
493
+ // write!(f, "{}", db.enum_variant_data(v).name.display(db.upcast()))?;
494
+ // }
495
+ // VariantId::StructId(s) => {
496
+ // write!(f, "{}", db.struct_data(s).name.display(db.upcast()))?
497
+ // }
498
+ // VariantId::UnionId(u) => {
499
+ // write!(f, "{}", db.union_data(u).name.display(db.upcast()))?
500
+ // }
501
+ // }
502
+ // }
503
+ // Ok(())
499
504
}
500
505
501
506
fn bug ( & self , fmt : fmt:: Arguments < ' _ > ) {
@@ -507,7 +512,7 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
507
512
}
508
513
}
509
514
510
- impl < ' p > fmt:: Debug for MatchCheckCtx < ' p > {
515
+ impl < ' db > fmt:: Debug for MatchCheckCtx < ' db > {
511
516
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
512
517
f. debug_struct ( "MatchCheckCtx" ) . finish ( )
513
518
}
0 commit comments