@@ -1053,7 +1053,8 @@ fn typeck_tables_of_with_fallback<'tcx>(
10531053 } ;
10541054
10551055 // Gather locals in statics (because of block expressions).
1056- GatherLocalsVisitor { fcx : & fcx, parent_id : id } . visit_body ( body) ;
1056+ GatherLocalsVisitor { fcx : & fcx, parent_id : id, within_fn_param : false }
1057+ . visit_body ( body) ;
10571058
10581059 fcx. check_expr_coercable_to_type ( & body. value , revealed_ty) ;
10591060
@@ -1156,6 +1157,10 @@ fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
11561157struct GatherLocalsVisitor < ' a , ' tcx > {
11571158 fcx : & ' a FnCtxt < ' a , ' tcx > ,
11581159 parent_id : hir:: HirId ,
1160+ // params are special cases of pats, but we want to handle them as
1161+ // *distinct* cases. so track when we are hitting a pat *within* an fn
1162+ // param.
1163+ within_fn_param : bool ,
11591164}
11601165
11611166impl < ' a , ' tcx > GatherLocalsVisitor < ' a , ' tcx > {
@@ -1226,13 +1231,25 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
12261231 intravisit:: walk_local ( self , local) ;
12271232 }
12281233
1234+ fn visit_param ( & mut self , param : & ' tcx hir:: Param < ' tcx > ) {
1235+ self . within_fn_param = true ;
1236+ intravisit:: walk_param ( self , param) ;
1237+ self . within_fn_param = false ;
1238+ }
1239+
12291240 // Add pattern bindings.
12301241 fn visit_pat ( & mut self , p : & ' tcx hir:: Pat < ' tcx > ) {
12311242 if let PatKind :: Binding ( _, _, ident, _) = p. kind {
12321243 let var_ty = self . assign ( p. span , p. hir_id , None ) ;
12331244
1234- if !self . fcx . tcx . features ( ) . unsized_locals {
1235- self . fcx . require_type_is_sized ( var_ty, p. span , traits:: VariableType ( p. hir_id ) ) ;
1245+ if self . within_fn_param {
1246+ if !self . fcx . tcx . features ( ) . unsized_fn_params {
1247+ self . fcx . require_type_is_sized ( var_ty, p. span , traits:: SizedArgumentType ) ;
1248+ }
1249+ } else {
1250+ if !self . fcx . tcx . features ( ) . unsized_locals {
1251+ self . fcx . require_type_is_sized ( var_ty, p. span , traits:: VariableType ( p. hir_id ) ) ;
1252+ }
12361253 }
12371254
12381255 debug ! (
@@ -1332,7 +1349,8 @@ fn check_fn<'a, 'tcx>(
13321349
13331350 let outer_def_id = tcx. closure_base_def_id ( hir. local_def_id ( fn_id) . to_def_id ( ) ) ;
13341351 let outer_hir_id = hir. as_local_hir_id ( outer_def_id. expect_local ( ) ) ;
1335- GatherLocalsVisitor { fcx : & fcx, parent_id : outer_hir_id } . visit_body ( body) ;
1352+ GatherLocalsVisitor { fcx : & fcx, parent_id : outer_hir_id, within_fn_param : false }
1353+ . visit_body ( body) ;
13361354
13371355 // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
13381356 // (as it's created inside the body itself, not passed in from outside).
@@ -1360,7 +1378,7 @@ fn check_fn<'a, 'tcx>(
13601378 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
13611379 // for simple cases like `fn foo(x: Trait)`,
13621380 // where we would error once on the parameter as a whole, and once on the binding `x`.
1363- if param. pat . simple_ident ( ) . is_none ( ) && !tcx. features ( ) . unsized_locals {
1381+ if param. pat . simple_ident ( ) . is_none ( ) && !tcx. features ( ) . unsized_fn_params {
13641382 fcx. require_type_is_sized ( param_ty, param. pat . span , traits:: SizedArgumentType ) ;
13651383 }
13661384
0 commit comments