2
2
3
3
mod check_match;
4
4
mod const_to_pat;
5
+ mod migration;
5
6
6
7
use std:: cmp:: Ordering ;
7
8
use std:: sync:: Arc ;
8
9
9
10
use rustc_abi:: { FieldIdx , Integer } ;
10
- use rustc_errors:: MultiSpan ;
11
11
use rustc_errors:: codes:: * ;
12
12
use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
13
13
use rustc_hir:: pat_util:: EnumerateAndAdjustIterator ;
14
14
use rustc_hir:: { self as hir, ByRef , Mutability , RangeEnd } ;
15
15
use rustc_index:: Idx ;
16
- use rustc_lint as lint;
17
16
use rustc_middle:: mir:: interpret:: LitToConstInput ;
18
17
use rustc_middle:: thir:: {
19
18
Ascription , FieldPat , LocalVarId , Pat , PatKind , PatRange , PatRangeBoundary ,
@@ -26,16 +25,16 @@ use rustc_span::{ErrorGuaranteed, Span};
26
25
use tracing:: { debug, instrument} ;
27
26
28
27
pub ( crate ) use self :: check_match:: check_match;
28
+ use self :: migration:: PatMigration ;
29
29
use crate :: errors:: * ;
30
- use crate :: fluent_generated as fluent;
31
30
32
31
struct PatCtxt < ' a , ' tcx > {
33
32
tcx : TyCtxt < ' tcx > ,
34
33
typing_env : ty:: TypingEnv < ' tcx > ,
35
34
typeck_results : & ' a ty:: TypeckResults < ' tcx > ,
36
35
37
36
/// Used by the Rust 2024 migration lint.
38
- rust_2024_migration_suggestion : Option < Rust2024IncompatiblePatSugg > ,
37
+ rust_2024_migration : Option < PatMigration < ' a > > ,
39
38
}
40
39
41
40
pub ( super ) fn pat_from_hir < ' a , ' tcx > (
@@ -44,59 +43,19 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
44
43
typeck_results : & ' a ty:: TypeckResults < ' tcx > ,
45
44
pat : & ' tcx hir:: Pat < ' tcx > ,
46
45
) -> Box < Pat < ' tcx > > {
47
- let migration_info = typeck_results. rust_2024_migration_desugared_pats ( ) . get ( pat. hir_id ) ;
48
46
let mut pcx = PatCtxt {
49
47
tcx,
50
48
typing_env,
51
49
typeck_results,
52
- rust_2024_migration_suggestion : migration_info. and_then ( |info| {
53
- Some ( Rust2024IncompatiblePatSugg {
54
- suggest_eliding_modes : info. suggest_eliding_modes ,
55
- suggestion : Vec :: new ( ) ,
56
- ref_pattern_count : 0 ,
57
- binding_mode_count : 0 ,
58
- default_mode_span : None ,
59
- default_mode_labels : Default :: default ( ) ,
60
- } )
61
- } ) ,
50
+ rust_2024_migration : typeck_results
51
+ . rust_2024_migration_desugared_pats ( )
52
+ . get ( pat. hir_id )
53
+ . map ( PatMigration :: new) ,
62
54
} ;
63
55
let result = pcx. lower_pattern ( pat) ;
64
56
debug ! ( "pat_from_hir({:?}) = {:?}" , pat, result) ;
65
- if let Some ( info) = migration_info
66
- && let Some ( sugg) = pcx. rust_2024_migration_suggestion
67
- {
68
- let mut spans =
69
- MultiSpan :: from_spans ( info. primary_labels . iter ( ) . map ( |( span, _) | * span) . collect ( ) ) ;
70
- for ( span, label) in & info. primary_labels {
71
- spans. push_span_label ( * span, label. clone ( ) ) ;
72
- }
73
- // If a relevant span is from at least edition 2024, this is a hard error.
74
- let is_hard_error = spans. primary_spans ( ) . iter ( ) . any ( |span| span. at_least_rust_2024 ( ) ) ;
75
- if is_hard_error {
76
- let mut err =
77
- tcx. dcx ( ) . struct_span_err ( spans, fluent:: mir_build_rust_2024_incompatible_pat) ;
78
- if let Some ( lint_info) = lint:: builtin:: RUST_2024_INCOMPATIBLE_PAT . future_incompatible {
79
- // provide the same reference link as the lint
80
- err. note ( format ! ( "for more information, see {}" , lint_info. reference) ) ;
81
- }
82
- err. arg ( "bad_modifiers" , info. bad_modifiers ) ;
83
- err. arg ( "bad_ref_pats" , info. bad_ref_pats ) ;
84
- err. arg ( "is_hard_error" , true ) ;
85
- err. subdiagnostic ( sugg) ;
86
- err. emit ( ) ;
87
- } else {
88
- tcx. emit_node_span_lint (
89
- lint:: builtin:: RUST_2024_INCOMPATIBLE_PAT ,
90
- pat. hir_id ,
91
- spans,
92
- Rust2024IncompatiblePat {
93
- sugg,
94
- bad_modifiers : info. bad_modifiers ,
95
- bad_ref_pats : info. bad_ref_pats ,
96
- is_hard_error,
97
- } ,
98
- ) ;
99
- }
57
+ if let Some ( m) = pcx. rust_2024_migration {
58
+ m. emit ( tcx, pat. hir_id ) ;
100
59
}
101
60
result
102
61
}
@@ -107,7 +66,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
107
66
self . typeck_results . pat_adjustments ( ) . get ( pat. hir_id ) . map_or ( & [ ] , |v| & * * v) ;
108
67
109
68
let mut opt_old_mode_span = None ;
110
- if let Some ( s) = & mut self . rust_2024_migration_suggestion
69
+ if let Some ( s) = & mut self . rust_2024_migration
111
70
&& !adjustments. is_empty ( )
112
71
{
113
72
let implicit_deref_mutbls = adjustments. iter ( ) . map ( |ref_ty| {
@@ -117,7 +76,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
117
76
mutbl
118
77
} ) ;
119
78
120
- if !s. suggest_eliding_modes {
79
+ if !s. info . suggest_eliding_modes {
121
80
let suggestion_str: String =
122
81
implicit_deref_mutbls. clone ( ) . map ( |mutbl| mutbl. ref_prefix_str ( ) ) . collect ( ) ;
123
82
s. suggestion . push ( ( pat. span . shrink_to_lo ( ) , suggestion_str) ) ;
@@ -169,7 +128,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
169
128
} )
170
129
} ) ;
171
130
172
- if let Some ( s) = & mut self . rust_2024_migration_suggestion
131
+ if let Some ( s) = & mut self . rust_2024_migration
173
132
&& let Some ( old_mode_span) = opt_old_mode_span
174
133
{
175
134
s. default_mode_span = old_mode_span;
@@ -368,15 +327,15 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
368
327
}
369
328
hir:: PatKind :: Ref ( subpattern, _) => {
370
329
// Track the default binding mode for the Rust 2024 migration suggestion.
371
- let old_mode_span = self . rust_2024_migration_suggestion . as_mut ( ) . and_then ( |s| {
330
+ let old_mode_span = self . rust_2024_migration . as_mut ( ) . and_then ( |s| {
372
331
if let Some ( ( default_mode_span, default_ref_mutbl) ) = s. default_mode_span {
373
332
// If this eats a by-ref default binding mode, label the binding mode.
374
333
s. default_mode_labels . insert ( default_mode_span, default_ref_mutbl) ;
375
334
}
376
335
s. default_mode_span . take ( )
377
336
} ) ;
378
337
let subpattern = self . lower_pattern ( subpattern) ;
379
- if let Some ( s) = & mut self . rust_2024_migration_suggestion {
338
+ if let Some ( s) = & mut self . rust_2024_migration {
380
339
s. default_mode_span = old_mode_span;
381
340
}
382
341
PatKind :: Deref { subpattern }
@@ -408,19 +367,19 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
408
367
. get ( pat. hir_id )
409
368
. expect ( "missing binding mode" ) ;
410
369
411
- if let Some ( s) = & mut self . rust_2024_migration_suggestion {
370
+ if let Some ( s) = & mut self . rust_2024_migration {
412
371
if explicit_ba != hir:: BindingMode :: NONE
413
372
&& let Some ( ( default_mode_span, default_ref_mutbl) ) = s. default_mode_span
414
373
{
415
374
// If this overrides a by-ref default binding mode, label the binding mode.
416
375
s. default_mode_labels . insert ( default_mode_span, default_ref_mutbl) ;
417
376
// If our suggestion is to elide redundnt modes, this will be one of them.
418
- if s. suggest_eliding_modes {
377
+ if s. info . suggest_eliding_modes {
419
378
s. suggestion . push ( ( pat. span . with_hi ( ident. span . lo ( ) ) , String :: new ( ) ) ) ;
420
379
s. binding_mode_count += 1 ;
421
380
}
422
381
}
423
- if !s. suggest_eliding_modes
382
+ if !s. info . suggest_eliding_modes
424
383
&& explicit_ba. 0 == ByRef :: No
425
384
&& let ByRef :: Yes ( mutbl) = mode. 0
426
385
{
0 commit comments