@@ -1027,6 +1027,21 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
10271027 ) ;
10281028 }
10291029 }
1030+
1031+ fn report_mixed_deref_pat_ctors (
1032+ & self ,
1033+ deref_pat : & crate :: pat:: DeconstructedPat < Self > ,
1034+ normal_pat : & crate :: pat:: DeconstructedPat < Self > ,
1035+ ) -> Self :: Error {
1036+ let deref_pattern_label = deref_pat. data ( ) . span ;
1037+ let normal_constructor_label = normal_pat. data ( ) . span ;
1038+ self . tcx . dcx ( ) . emit_err ( errors:: MixedDerefPatternConstructors {
1039+ spans : vec ! [ deref_pattern_label, normal_constructor_label] ,
1040+ smart_pointer_ty : deref_pat. ty ( ) . inner ( ) ,
1041+ deref_pattern_label,
1042+ normal_constructor_label,
1043+ } )
1044+ }
10301045}
10311046
10321047/// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.
@@ -1055,13 +1070,6 @@ pub fn analyze_match<'p, 'tcx>(
10551070) -> Result < UsefulnessReport < ' p , ' tcx > , ErrorGuaranteed > {
10561071 let scrut_ty = tycx. reveal_opaque_ty ( scrut_ty) ;
10571072
1058- // The analysis doesn't support deref patterns mixed with normal constructors; error if present.
1059- // FIXME(deref_patterns): This only needs to run when a deref pattern was found during lowering.
1060- if tycx. tcx . features ( ) . deref_patterns ( ) {
1061- let pat_column = PatternColumn :: new ( arms) ;
1062- detect_mixed_deref_pat_ctors ( tycx, & pat_column) ?;
1063- }
1064-
10651073 let scrut_validity = PlaceValidity :: from_bool ( tycx. known_valid_scrutinee ) ;
10661074 let report = compute_match_usefulness (
10671075 tycx,
@@ -1080,48 +1088,3 @@ pub fn analyze_match<'p, 'tcx>(
10801088
10811089 Ok ( report)
10821090}
1083-
1084- // FIXME(deref_patterns): Currently it's the responsibility of the frontend (rustc or rust-analyzer)
1085- // to ensure that deref patterns don't appear in the same column as normal constructors. Deref
1086- // patterns aren't currently implemented in rust-analyzer, but should they be, the columnwise check
1087- // here could be made generic and shared between frontends.
1088- fn detect_mixed_deref_pat_ctors < ' p , ' tcx > (
1089- cx : & RustcPatCtxt < ' p , ' tcx > ,
1090- column : & PatternColumn < ' p , RustcPatCtxt < ' p , ' tcx > > ,
1091- ) -> Result < ( ) , ErrorGuaranteed > {
1092- let Some ( & ty) = column. head_ty ( ) else {
1093- return Ok ( ( ) ) ;
1094- } ;
1095-
1096- // Check for a mix of deref patterns and normal constructors.
1097- let mut normal_ctor_span = None ;
1098- let mut deref_pat_span = None ;
1099- for pat in column. iter ( ) {
1100- match pat. ctor ( ) {
1101- // The analysis can handle mixing deref patterns with wildcards and opaque patterns.
1102- Wildcard | Opaque ( _) => { }
1103- DerefPattern ( _) => deref_pat_span = Some ( pat. data ( ) . span ) ,
1104- // Nothing else can be compared to deref patterns in `Constructor::is_covered_by`.
1105- _ => normal_ctor_span = Some ( pat. data ( ) . span ) ,
1106- }
1107- }
1108- if let Some ( normal_constructor_label) = normal_ctor_span
1109- && let Some ( deref_pattern_label) = deref_pat_span
1110- {
1111- return Err ( cx. tcx . dcx ( ) . emit_err ( errors:: MixedDerefPatternConstructors {
1112- spans : vec ! [ deref_pattern_label, normal_constructor_label] ,
1113- smart_pointer_ty : ty. inner ( ) ,
1114- deref_pattern_label,
1115- normal_constructor_label,
1116- } ) ) ;
1117- }
1118-
1119- // Specialize and recurse into the patterns' fields.
1120- let set = column. analyze_ctors ( cx, & ty) ?;
1121- for ctor in set. present {
1122- for specialized_column in column. specialize ( cx, & ty, & ctor) . iter ( ) {
1123- detect_mixed_deref_pat_ctors ( cx, specialized_column) ?;
1124- }
1125- }
1126- Ok ( ( ) )
1127- }
0 commit comments