@@ -20,7 +20,6 @@ mod lint;
20
20
mod object_safety;
21
21
22
22
use crate :: bounds:: Bounds ;
23
- use crate :: collect:: HirPlaceholderCollector ;
24
23
use crate :: errors:: { AmbiguousLifetimeBound , WildPatTy } ;
25
24
use crate :: hir_ty_lowering:: errors:: { prohibit_assoc_item_constraint, GenericsArgsErrExtend } ;
26
25
use crate :: hir_ty_lowering:: generics:: { check_generic_arg_count, lower_generic_args} ;
@@ -34,7 +33,6 @@ use rustc_errors::{
34
33
use rustc_hir as hir;
35
34
use rustc_hir:: def:: { CtorOf , DefKind , Namespace , Res } ;
36
35
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
37
- use rustc_hir:: intravisit:: { walk_generics, Visitor as _} ;
38
36
use rustc_hir:: { GenericArg , GenericArgs , HirId } ;
39
37
use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
40
38
use rustc_infer:: traits:: ObligationCause ;
@@ -157,6 +155,14 @@ pub trait HirTyLowerer<'tcx> {
157
155
poly_trait_ref : ty:: PolyTraitRef < ' tcx > ,
158
156
) -> Ty < ' tcx > ;
159
157
158
+ fn lower_fn_sig (
159
+ & self ,
160
+ decl : & hir:: FnDecl < ' tcx > ,
161
+ generics : Option < & hir:: Generics < ' _ > > ,
162
+ hir_id : HirId ,
163
+ hir_ty : Option < & hir:: Ty < ' _ > > ,
164
+ ) -> ( Vec < Ty < ' tcx > > , Ty < ' tcx > ) ;
165
+
160
166
/// Returns `AdtDef` if `ty` is an ADT.
161
167
///
162
168
/// Note that `ty` might be a alias type that needs normalization.
@@ -2306,92 +2312,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
2306
2312
let bound_vars = tcx. late_bound_vars ( hir_id) ;
2307
2313
debug ! ( ?bound_vars) ;
2308
2314
2309
- // We proactively collect all the inferred type params to emit a single error per fn def.
2310
- let mut visitor = HirPlaceholderCollector :: default ( ) ;
2311
- let mut infer_replacements = vec ! [ ] ;
2312
-
2313
- if let Some ( generics) = generics {
2314
- walk_generics ( & mut visitor, generics) ;
2315
- }
2316
-
2317
- let input_tys: Vec < _ > = decl
2318
- . inputs
2319
- . iter ( )
2320
- . enumerate ( )
2321
- . map ( |( i, a) | {
2322
- if let hir:: TyKind :: Infer = a. kind
2323
- && !self . allow_infer ( )
2324
- {
2325
- if let Some ( suggested_ty) =
2326
- self . suggest_trait_fn_ty_for_impl_fn_infer ( hir_id, Some ( i) )
2327
- {
2328
- infer_replacements. push ( ( a. span , suggested_ty. to_string ( ) ) ) ;
2329
- return Ty :: new_error_with_message (
2330
- self . tcx ( ) ,
2331
- a. span ,
2332
- suggested_ty. to_string ( ) ,
2333
- ) ;
2334
- }
2335
- }
2336
-
2337
- // Only visit the type looking for `_` if we didn't fix the type above
2338
- visitor. visit_ty ( a) ;
2339
- self . lower_arg_ty ( a, None )
2340
- } )
2341
- . collect ( ) ;
2342
-
2343
- let output_ty = match decl. output {
2344
- hir:: FnRetTy :: Return ( output) => {
2345
- if let hir:: TyKind :: Infer = output. kind
2346
- && !self . allow_infer ( )
2347
- && let Some ( suggested_ty) =
2348
- self . suggest_trait_fn_ty_for_impl_fn_infer ( hir_id, None )
2349
- {
2350
- infer_replacements. push ( ( output. span , suggested_ty. to_string ( ) ) ) ;
2351
- Ty :: new_error_with_message ( self . tcx ( ) , output. span , suggested_ty. to_string ( ) )
2352
- } else {
2353
- visitor. visit_ty ( output) ;
2354
- self . lower_ty ( output)
2355
- }
2356
- }
2357
- hir:: FnRetTy :: DefaultReturn ( ..) => tcx. types . unit ,
2358
- } ;
2315
+ let ( input_tys, output_ty) = self . lower_fn_sig ( decl, generics, hir_id, hir_ty) ;
2359
2316
2360
2317
debug ! ( ?output_ty) ;
2361
2318
2362
2319
let fn_ty = tcx. mk_fn_sig ( input_tys, output_ty, decl. c_variadic , safety, abi) ;
2363
2320
let bare_fn_ty = ty:: Binder :: bind_with_vars ( fn_ty, bound_vars) ;
2364
2321
2365
- if !self . allow_infer ( ) && !( visitor. 0 . is_empty ( ) && infer_replacements. is_empty ( ) ) {
2366
- // We always collect the spans for placeholder types when evaluating `fn`s, but we
2367
- // only want to emit an error complaining about them if infer types (`_`) are not
2368
- // allowed. `allow_infer` gates this behavior. We check for the presence of
2369
- // `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
2370
-
2371
- let mut diag = crate :: collect:: placeholder_type_error_diag (
2372
- tcx,
2373
- generics,
2374
- visitor. 0 ,
2375
- infer_replacements. iter ( ) . map ( |( s, _) | * s) . collect ( ) ,
2376
- true ,
2377
- hir_ty,
2378
- "function" ,
2379
- ) ;
2380
-
2381
- if !infer_replacements. is_empty ( ) {
2382
- diag. multipart_suggestion (
2383
- format ! (
2384
- "try replacing `_` with the type{} in the corresponding trait method signature" ,
2385
- rustc_errors:: pluralize!( infer_replacements. len( ) ) ,
2386
- ) ,
2387
- infer_replacements,
2388
- Applicability :: MachineApplicable ,
2389
- ) ;
2390
- }
2391
-
2392
- self . set_tainted_by_errors ( diag. emit ( ) ) ;
2393
- }
2394
-
2395
2322
// Find any late-bound regions declared in return type that do
2396
2323
// not appear in the arguments. These are not well-formed.
2397
2324
//
@@ -2421,7 +2348,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
2421
2348
/// corresponding function in the trait that the impl implements, if it exists.
2422
2349
/// If arg_idx is Some, then it corresponds to an input type index, otherwise it
2423
2350
/// corresponds to the return type.
2424
- fn suggest_trait_fn_ty_for_impl_fn_infer (
2351
+ pub ( super ) fn suggest_trait_fn_ty_for_impl_fn_infer (
2425
2352
& self ,
2426
2353
fn_hir_id : HirId ,
2427
2354
arg_idx : Option < usize > ,
0 commit comments