@@ -4,10 +4,9 @@ use std::fmt;
44
55use hir_def:: { DefWithBodyId , EnumId , EnumVariantId , HasModule , LocalFieldId , ModuleId , VariantId } ;
66use once_cell:: unsync:: Lazy ;
7- use rustc_hash :: FxHashMap ;
7+ use rustc_index :: IndexVec ;
88use rustc_pattern_analysis:: {
99 constructor:: { Constructor , ConstructorSet , VariantVisibility } ,
10- index:: IdxContainer ,
1110 usefulness:: { compute_match_usefulness, PlaceValidity , UsefulnessReport } ,
1211 Captures , PatCx , PrivateUninhabitedField ,
1312} ;
@@ -26,10 +25,10 @@ use super::{is_box, FieldPat, Pat, PatKind};
2625use Constructor :: * ;
2726
2827// 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 > > ;
3332
3433/// [Constructor] uses this in unimplemented variants.
3534/// It allows porting match expressions from upstream algorithm without losing semantics.
@@ -54,23 +53,27 @@ impl EnumVariantContiguousIndex {
5453 }
5554}
5655
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+
5766#[ derive( Clone ) ]
58- pub ( crate ) struct MatchCheckCtx < ' p > {
67+ pub ( crate ) struct MatchCheckCtx < ' db > {
5968 module : ModuleId ,
6069 body : DefWithBodyId ,
61- pub ( crate ) db : & ' p dyn HirDatabase ,
70+ pub ( crate ) db : & ' db dyn HirDatabase ,
6271 exhaustive_patterns : bool ,
6372 min_exhaustive_patterns : bool ,
6473}
6574
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 {
7477 let def_map = db. crate_def_map ( module. krate ( ) ) ;
7578 let exhaustive_patterns = def_map. is_unstable_feature_enabled ( "exhaustive_patterns" ) ;
7679 let min_exhaustive_patterns =
@@ -80,9 +83,9 @@ impl<'p> MatchCheckCtx<'p> {
8083
8184 pub ( crate ) fn compute_match_usefulness (
8285 & self ,
83- arms : & [ MatchArm < ' p > ] ,
86+ arms : & [ MatchArm < ' db > ] ,
8487 scrut_ty : Ty ,
85- ) -> Result < UsefulnessReport < ' p , Self > , ( ) > {
88+ ) -> Result < UsefulnessReport < ' db , Self > , ( ) > {
8689 // FIXME: Determine place validity correctly. For now, err on the safe side.
8790 let place_validity = PlaceValidity :: MaybeInvalid ;
8891 // Measured to take ~100ms on modern hardware.
@@ -101,7 +104,7 @@ impl<'p> MatchCheckCtx<'p> {
101104 }
102105
103106 fn variant_id_for_adt (
104- db : & ' p dyn HirDatabase ,
107+ db : & ' db dyn HirDatabase ,
105108 ctor : & Constructor < Self > ,
106109 adt : hir_def:: AdtId ,
107110 ) -> Option < VariantId > {
@@ -126,7 +129,7 @@ impl<'p> MatchCheckCtx<'p> {
126129 & ' a self ,
127130 ty : & ' a Ty ,
128131 variant : VariantId ,
129- ) -> impl Iterator < Item = ( LocalFieldId , Ty ) > + Captures < ' a > + Captures < ' p > {
132+ ) -> impl Iterator < Item = ( LocalFieldId , Ty ) > + Captures < ' a > + Captures < ' db > {
130133 let ( _, substs) = ty. as_adt ( ) . unwrap ( ) ;
131134
132135 let field_tys = self . db . field_types ( variant) ;
@@ -139,8 +142,8 @@ impl<'p> MatchCheckCtx<'p> {
139142 } )
140143 }
141144
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 ) ] ;
144147 let ctor;
145148 let mut fields: Vec < _ > ;
146149 let arity;
@@ -228,6 +231,11 @@ impl<'p> MatchCheckCtx<'p> {
228231 fields = Vec :: new ( ) ;
229232 arity = 0 ;
230233 }
234+ PatKind :: Never => {
235+ ctor = Never ;
236+ fields = Vec :: new ( ) ;
237+ arity = 0 ;
238+ }
231239 PatKind :: Or { pats } => {
232240 ctor = Or ;
233241 fields = pats
@@ -238,11 +246,10 @@ impl<'p> MatchCheckCtx<'p> {
238246 arity = pats. len ( ) ;
239247 }
240248 }
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 ( ) , ( ) )
243250 }
244251
245- pub ( crate ) fn hoist_witness_pat ( & self , pat : & WitnessPat < ' p > ) -> Pat {
252+ pub ( crate ) fn hoist_witness_pat ( & self , pat : & WitnessPat < ' db > ) -> Pat {
246253 let mut subpatterns = pat. iter_fields ( ) . map ( |p| self . hoist_witness_pat ( p) ) ;
247254 let kind = match pat. ctor ( ) {
248255 & Bool ( value) => PatKind :: LiteralBool { value } ,
@@ -290,6 +297,7 @@ impl<'p> MatchCheckCtx<'p> {
290297 Slice ( _) => unimplemented ! ( ) ,
291298 & Str ( void) => match void { } ,
292299 Wildcard | NonExhaustive | Hidden | PrivateUninhabited => PatKind :: Wild ,
300+ Never => PatKind :: Never ,
293301 Missing | F32Range ( ..) | F64Range ( ..) | Opaque ( ..) | Or => {
294302 never ! ( "can't convert to pattern: {:?}" , pat. ctor( ) ) ;
295303 PatKind :: Wild
@@ -299,13 +307,13 @@ impl<'p> MatchCheckCtx<'p> {
299307 }
300308}
301309
302- impl < ' p > PatCx for MatchCheckCtx < ' p > {
310+ impl < ' db > PatCx for MatchCheckCtx < ' db > {
303311 type Error = ( ) ;
304312 type Ty = Ty ;
305313 type VariantIdx = EnumVariantContiguousIndex ;
306314 type StrLit = Void ;
307315 type ArmData = ( ) ;
308- type PatData = PatData < ' p > ;
316+ type PatData = ( ) ;
309317
310318 fn is_exhaustive_patterns_feature_on ( & self ) -> bool {
311319 self . exhaustive_patterns
@@ -339,8 +347,8 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
339347 } ,
340348 Ref => 1 ,
341349 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 ,
344352 Or => {
345353 never ! ( "The `Or` constructor doesn't have a fixed arity" ) ;
346354 0
@@ -402,8 +410,10 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
402410 }
403411 } ,
404412 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+ }
407417 Or => {
408418 never ! ( "called `Fields::wildcards` on an `Or` ctor" ) ;
409419 smallvec ! [ ]
@@ -442,25 +452,19 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
442452 if enum_data. variants . is_empty ( ) && !is_declared_nonexhaustive {
443453 ConstructorSet :: NoConstructors
444454 } 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 ( ) {
450457 let is_uninhabited =
451458 is_enum_variant_uninhabited_from ( cx. db , variant, subst, cx. module ) ;
452459 let visibility = if is_uninhabited {
453460 VariantVisibility :: Empty
454461 } else {
455462 VariantVisibility :: Visible
456463 } ;
457- variants. insert ( EnumVariantContiguousIndex ( i ) , visibility) ;
464+ variants. push ( visibility) ;
458465 }
459466
460- ConstructorSet :: Variants {
461- variants : IdxContainer ( variants) ,
462- non_exhaustive : is_declared_nonexhaustive,
463- }
467+ ConstructorSet :: Variants { variants, non_exhaustive : is_declared_nonexhaustive }
464468 }
465469 }
466470 TyKind :: Adt ( AdtId ( hir_def:: AdtId :: UnionId ( _) ) , _) => ConstructorSet :: Union ,
@@ -476,26 +480,27 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
476480
477481 fn write_variant_name (
478482 f : & mut fmt:: Formatter < ' _ > ,
479- pat : & rustc_pattern_analysis:: pat:: DeconstructedPat < Self > ,
483+ _ctor : & Constructor < Self > ,
484+ _ty : & Self :: Ty ,
480485 ) -> 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(())
499504 }
500505
501506 fn bug ( & self , fmt : fmt:: Arguments < ' _ > ) {
@@ -507,7 +512,7 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
507512 }
508513}
509514
510- impl < ' p > fmt:: Debug for MatchCheckCtx < ' p > {
515+ impl < ' db > fmt:: Debug for MatchCheckCtx < ' db > {
511516 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
512517 f. debug_struct ( "MatchCheckCtx" ) . finish ( )
513518 }
0 commit comments