@@ -19,7 +19,9 @@ use rustc_ast::visit::{
19
19
use rustc_ast:: * ;
20
20
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexMap } ;
21
21
use rustc_errors:: codes:: * ;
22
- use rustc_errors:: { Applicability , DiagArgValue , IntoDiagArg , StashKey , Suggestions } ;
22
+ use rustc_errors:: {
23
+ Applicability , DiagArgValue , ErrorGuaranteed , IntoDiagArg , StashKey , Suggestions ,
24
+ } ;
23
25
use rustc_hir:: def:: Namespace :: { self , * } ;
24
26
use rustc_hir:: def:: { self , CtorKind , DefKind , LifetimeRes , NonMacroAttrKind , PartialRes , PerNS } ;
25
27
use rustc_hir:: def_id:: { CRATE_DEF_ID , DefId , LOCAL_CRATE , LocalDefId } ;
@@ -264,12 +266,17 @@ impl RibKind<'_> {
264
266
#[ derive( Debug ) ]
265
267
pub ( crate ) struct Rib < ' ra , R = Res > {
266
268
pub bindings : IdentMap < R > ,
269
+ pub patterns_with_skipped_bindings : FxHashMap < DefId , Vec < ( Span , Result < ( ) , ErrorGuaranteed > ) > > ,
267
270
pub kind : RibKind < ' ra > ,
268
271
}
269
272
270
273
impl < ' ra , R > Rib < ' ra , R > {
271
274
fn new ( kind : RibKind < ' ra > ) -> Rib < ' ra , R > {
272
- Rib { bindings : Default :: default ( ) , kind }
275
+ Rib {
276
+ bindings : Default :: default ( ) ,
277
+ patterns_with_skipped_bindings : Default :: default ( ) ,
278
+ kind,
279
+ }
273
280
}
274
281
}
275
282
@@ -3775,6 +3782,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
3775
3782
/// When a whole or-pattern has been dealt with, the thing happens.
3776
3783
///
3777
3784
/// See the implementation and `fresh_binding` for more details.
3785
+ #[ tracing:: instrument( skip( self , bindings) , level = "debug" ) ]
3778
3786
fn resolve_pattern_inner (
3779
3787
& mut self ,
3780
3788
pat : & Pat ,
@@ -3783,7 +3791,6 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
3783
3791
) {
3784
3792
// Visit all direct subpatterns of this pattern.
3785
3793
pat. walk ( & mut |pat| {
3786
- debug ! ( "resolve_pattern pat={:?} node={:?}" , pat, pat. kind) ;
3787
3794
match pat. kind {
3788
3795
PatKind :: Ident ( bmode, ident, ref sub) => {
3789
3796
// First try to resolve the identifier as some existing entity,
@@ -3809,8 +3816,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
3809
3816
PatKind :: Path ( ref qself, ref path) => {
3810
3817
self . smart_resolve_path ( pat. id , qself, path, PathSource :: Pat ) ;
3811
3818
}
3812
- PatKind :: Struct ( ref qself, ref path, .. ) => {
3819
+ PatKind :: Struct ( ref qself, ref path, ref _fields , ref rest ) => {
3813
3820
self . smart_resolve_path ( pat. id , qself, path, PathSource :: Struct ) ;
3821
+ self . record_patterns_with_skipped_bindings ( pat, rest) ;
3814
3822
}
3815
3823
PatKind :: Or ( ref ps) => {
3816
3824
// Add a new set of bindings to the stack. `Or` here records that when a
@@ -3843,6 +3851,30 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
3843
3851
} ) ;
3844
3852
}
3845
3853
3854
+ fn record_patterns_with_skipped_bindings ( & mut self , pat : & Pat , rest : & ast:: PatFieldsRest ) {
3855
+ match rest {
3856
+ ast:: PatFieldsRest :: Rest | ast:: PatFieldsRest :: Recovered ( _) => {
3857
+ // Record that the pattern doesn't introduce all the bindings it could.
3858
+ if let Some ( partial_res) = self . r . partial_res_map . get ( & pat. id )
3859
+ && let Some ( res) = partial_res. full_res ( )
3860
+ && let Some ( def_id) = res. opt_def_id ( )
3861
+ {
3862
+ self . ribs [ ValueNS ]
3863
+ . last_mut ( )
3864
+ . unwrap ( )
3865
+ . patterns_with_skipped_bindings
3866
+ . entry ( def_id)
3867
+ . or_default ( )
3868
+ . push ( ( pat. span , match rest {
3869
+ ast:: PatFieldsRest :: Recovered ( guar) => Err ( * guar) ,
3870
+ _ => Ok ( ( ) ) ,
3871
+ } ) ) ;
3872
+ }
3873
+ }
3874
+ ast:: PatFieldsRest :: None => { }
3875
+ }
3876
+ }
3877
+
3846
3878
fn fresh_binding (
3847
3879
& mut self ,
3848
3880
ident : Ident ,
0 commit comments