@@ -19,7 +19,9 @@ use rustc_ast::visit::{
1919use rustc_ast:: * ;
2020use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexMap } ;
2121use rustc_errors:: codes:: * ;
22- use rustc_errors:: { Applicability , DiagArgValue , IntoDiagArg , StashKey , Suggestions } ;
22+ use rustc_errors:: {
23+ Applicability , DiagArgValue , ErrorGuaranteed , IntoDiagArg , StashKey , Suggestions ,
24+ } ;
2325use rustc_hir:: def:: Namespace :: { self , * } ;
2426use rustc_hir:: def:: { self , CtorKind , DefKind , LifetimeRes , NonMacroAttrKind , PartialRes , PerNS } ;
2527use rustc_hir:: def_id:: { CRATE_DEF_ID , DefId , LOCAL_CRATE , LocalDefId } ;
@@ -264,12 +266,17 @@ impl RibKind<'_> {
264266#[ derive( Debug ) ]
265267pub ( crate ) struct Rib < ' ra , R = Res > {
266268 pub bindings : IdentMap < R > ,
269+ pub patterns_with_skipped_bindings : FxHashMap < DefId , Vec < ( Span , Result < ( ) , ErrorGuaranteed > ) > > ,
267270 pub kind : RibKind < ' ra > ,
268271}
269272
270273impl < ' ra , R > Rib < ' ra , R > {
271274 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+ }
273280 }
274281}
275282
@@ -3775,6 +3782,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37753782 /// When a whole or-pattern has been dealt with, the thing happens.
37763783 ///
37773784 /// See the implementation and `fresh_binding` for more details.
3785+ #[ tracing:: instrument( skip( self , bindings) , level = "debug" ) ]
37783786 fn resolve_pattern_inner (
37793787 & mut self ,
37803788 pat : & Pat ,
@@ -3783,7 +3791,6 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37833791 ) {
37843792 // Visit all direct subpatterns of this pattern.
37853793 pat. walk ( & mut |pat| {
3786- debug ! ( "resolve_pattern pat={:?} node={:?}" , pat, pat. kind) ;
37873794 match pat. kind {
37883795 PatKind :: Ident ( bmode, ident, ref sub) => {
37893796 // 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> {
38093816 PatKind :: Path ( ref qself, ref path) => {
38103817 self . smart_resolve_path ( pat. id , qself, path, PathSource :: Pat ) ;
38113818 }
3812- PatKind :: Struct ( ref qself, ref path, .. ) => {
3819+ PatKind :: Struct ( ref qself, ref path, ref _fields , ref rest ) => {
38133820 self . smart_resolve_path ( pat. id , qself, path, PathSource :: Struct ) ;
3821+ self . record_patterns_with_skipped_bindings ( pat, rest) ;
38143822 }
38153823 PatKind :: Or ( ref ps) => {
38163824 // 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> {
38433851 } ) ;
38443852 }
38453853
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+
38463878 fn fresh_binding (
38473879 & mut self ,
38483880 ident : Ident ,
0 commit comments