@@ -6,15 +6,20 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
6
6
use rustc_middle:: ty:: Ty ;
7
7
use rustc_span:: Span ;
8
8
use rustc_trait_selection:: traits;
9
+ use std:: mem;
9
10
10
11
pub ( super ) struct GatherLocalsVisitor < ' a , ' tcx > {
11
12
fcx : & ' a FnCtxt < ' a , ' tcx > ,
12
13
parent_id : hir:: HirId ,
14
+ // parameters are special cases of patterns, but we want to handle them as
15
+ // *distinct* cases. so track when we are hitting a pattern *within* an fn
16
+ // parameter.
17
+ outermost_fn_param_pat : bool ,
13
18
}
14
19
15
20
impl < ' a , ' tcx > GatherLocalsVisitor < ' a , ' tcx > {
16
21
pub ( super ) fn new ( fcx : & ' a FnCtxt < ' a , ' tcx > , parent_id : hir:: HirId ) -> Self {
17
- Self { fcx, parent_id }
22
+ Self { fcx, parent_id, outermost_fn_param_pat : false }
18
23
}
19
24
20
25
fn assign ( & mut self , span : Span , nid : hir:: HirId , ty_opt : Option < LocalTy < ' tcx > > ) -> Ty < ' tcx > {
@@ -88,13 +93,29 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
88
93
intravisit:: walk_local ( self , local) ;
89
94
}
90
95
96
+ fn visit_param ( & mut self , param : & ' tcx hir:: Param < ' tcx > ) {
97
+ let old_outermost_fn_param_pat = mem:: replace ( & mut self . outermost_fn_param_pat , true ) ;
98
+ intravisit:: walk_param ( self , param) ;
99
+ self . outermost_fn_param_pat = old_outermost_fn_param_pat;
100
+ }
101
+
91
102
// Add pattern bindings.
92
103
fn visit_pat ( & mut self , p : & ' tcx hir:: Pat < ' tcx > ) {
93
104
if let PatKind :: Binding ( _, _, ident, _) = p. kind {
94
105
let var_ty = self . assign ( p. span , p. hir_id , None ) ;
95
106
96
- if !self . fcx . tcx . features ( ) . unsized_locals {
97
- self . fcx . require_type_is_sized ( var_ty, p. span , traits:: VariableType ( p. hir_id ) ) ;
107
+ if self . outermost_fn_param_pat {
108
+ if !self . fcx . tcx . features ( ) . unsized_fn_params {
109
+ self . fcx . require_type_is_sized (
110
+ var_ty,
111
+ p. span ,
112
+ traits:: SizedArgumentType ( Some ( p. span ) ) ,
113
+ ) ;
114
+ }
115
+ } else {
116
+ if !self . fcx . tcx . features ( ) . unsized_locals {
117
+ self . fcx . require_type_is_sized ( var_ty, p. span , traits:: VariableType ( p. hir_id ) ) ;
118
+ }
98
119
}
99
120
100
121
debug ! (
@@ -104,7 +125,9 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
104
125
var_ty
105
126
) ;
106
127
}
128
+ let old_outermost_fn_param_pat = mem:: replace ( & mut self . outermost_fn_param_pat , false ) ;
107
129
intravisit:: walk_pat ( self , p) ;
130
+ self . outermost_fn_param_pat = old_outermost_fn_param_pat;
108
131
}
109
132
110
133
// Don't descend into the bodies of nested closures.
0 commit comments