@@ -6,15 +6,20 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
66use rustc_middle:: ty:: Ty ;
77use rustc_span:: Span ;
88use rustc_trait_selection:: traits;
9+ use std:: mem;
910
1011pub ( super ) struct GatherLocalsVisitor < ' a , ' tcx > {
1112 fcx : & ' a FnCtxt < ' a , ' tcx > ,
1213 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 ,
1318}
1419
1520impl < ' a , ' tcx > GatherLocalsVisitor < ' a , ' tcx > {
1621 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 }
1823 }
1924
2025 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> {
8893 intravisit:: walk_local ( self , local) ;
8994 }
9095
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+
91102 // Add pattern bindings.
92103 fn visit_pat ( & mut self , p : & ' tcx hir:: Pat < ' tcx > ) {
93104 if let PatKind :: Binding ( _, _, ident, _) = p. kind {
94105 let var_ty = self . assign ( p. span , p. hir_id , None ) ;
95106
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+ }
98119 }
99120
100121 debug ! (
@@ -104,7 +125,9 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
104125 var_ty
105126 ) ;
106127 }
128+ let old_outermost_fn_param_pat = mem:: replace ( & mut self . outermost_fn_param_pat , false ) ;
107129 intravisit:: walk_pat ( self , p) ;
130+ self . outermost_fn_param_pat = old_outermost_fn_param_pat;
108131 }
109132
110133 // Don't descend into the bodies of nested closures.
0 commit comments