@@ -20,7 +20,6 @@ mod lint;
2020mod object_safety;
2121
2222use crate :: bounds:: Bounds ;
23- use crate :: collect:: HirPlaceholderCollector ;
2423use crate :: errors:: { AmbiguousLifetimeBound , WildPatTy } ;
2524use crate :: hir_ty_lowering:: errors:: { prohibit_assoc_item_constraint, GenericsArgsErrExtend } ;
2625use crate :: hir_ty_lowering:: generics:: { check_generic_arg_count, lower_generic_args} ;
@@ -34,7 +33,6 @@ use rustc_errors::{
3433use rustc_hir as hir;
3534use rustc_hir:: def:: { CtorOf , DefKind , Namespace , Res } ;
3635use rustc_hir:: def_id:: { DefId , LocalDefId } ;
37- use rustc_hir:: intravisit:: { walk_generics, Visitor as _} ;
3836use rustc_hir:: { GenericArg , GenericArgs , HirId } ;
3937use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
4038use rustc_infer:: traits:: ObligationCause ;
@@ -157,6 +155,14 @@ pub trait HirTyLowerer<'tcx> {
157155 poly_trait_ref : ty:: PolyTraitRef < ' tcx > ,
158156 ) -> Ty < ' tcx > ;
159157
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+
160166 /// Returns `AdtDef` if `ty` is an ADT.
161167 ///
162168 /// Note that `ty` might be a alias type that needs normalization.
@@ -2290,92 +2296,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22902296 let bound_vars = tcx. late_bound_vars ( hir_id) ;
22912297 debug ! ( ?bound_vars) ;
22922298
2293- // We proactively collect all the inferred type params to emit a single error per fn def.
2294- let mut visitor = HirPlaceholderCollector :: default ( ) ;
2295- let mut infer_replacements = vec ! [ ] ;
2296-
2297- if let Some ( generics) = generics {
2298- walk_generics ( & mut visitor, generics) ;
2299- }
2300-
2301- let input_tys: Vec < _ > = decl
2302- . inputs
2303- . iter ( )
2304- . enumerate ( )
2305- . map ( |( i, a) | {
2306- if let hir:: TyKind :: Infer = a. kind
2307- && !self . allow_infer ( )
2308- {
2309- if let Some ( suggested_ty) =
2310- self . suggest_trait_fn_ty_for_impl_fn_infer ( hir_id, Some ( i) )
2311- {
2312- infer_replacements. push ( ( a. span , suggested_ty. to_string ( ) ) ) ;
2313- return Ty :: new_error_with_message (
2314- self . tcx ( ) ,
2315- a. span ,
2316- suggested_ty. to_string ( ) ,
2317- ) ;
2318- }
2319- }
2320-
2321- // Only visit the type looking for `_` if we didn't fix the type above
2322- visitor. visit_ty ( a) ;
2323- self . lower_arg_ty ( a, None )
2324- } )
2325- . collect ( ) ;
2326-
2327- let output_ty = match decl. output {
2328- hir:: FnRetTy :: Return ( output) => {
2329- if let hir:: TyKind :: Infer = output. kind
2330- && !self . allow_infer ( )
2331- && let Some ( suggested_ty) =
2332- self . suggest_trait_fn_ty_for_impl_fn_infer ( hir_id, None )
2333- {
2334- infer_replacements. push ( ( output. span , suggested_ty. to_string ( ) ) ) ;
2335- Ty :: new_error_with_message ( self . tcx ( ) , output. span , suggested_ty. to_string ( ) )
2336- } else {
2337- visitor. visit_ty ( output) ;
2338- self . lower_ty ( output)
2339- }
2340- }
2341- hir:: FnRetTy :: DefaultReturn ( ..) => tcx. types . unit ,
2342- } ;
2299+ let ( input_tys, output_ty) = self . lower_fn_sig ( decl, generics, hir_id, hir_ty) ;
23432300
23442301 debug ! ( ?output_ty) ;
23452302
23462303 let fn_ty = tcx. mk_fn_sig ( input_tys, output_ty, decl. c_variadic , safety, abi) ;
23472304 let bare_fn_ty = ty:: Binder :: bind_with_vars ( fn_ty, bound_vars) ;
23482305
2349- if !self . allow_infer ( ) && !( visitor. 0 . is_empty ( ) && infer_replacements. is_empty ( ) ) {
2350- // We always collect the spans for placeholder types when evaluating `fn`s, but we
2351- // only want to emit an error complaining about them if infer types (`_`) are not
2352- // allowed. `allow_infer` gates this behavior. We check for the presence of
2353- // `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
2354-
2355- let mut diag = crate :: collect:: placeholder_type_error_diag (
2356- tcx,
2357- generics,
2358- visitor. 0 ,
2359- infer_replacements. iter ( ) . map ( |( s, _) | * s) . collect ( ) ,
2360- true ,
2361- hir_ty,
2362- "function" ,
2363- ) ;
2364-
2365- if !infer_replacements. is_empty ( ) {
2366- diag. multipart_suggestion (
2367- format ! (
2368- "try replacing `_` with the type{} in the corresponding trait method signature" ,
2369- rustc_errors:: pluralize!( infer_replacements. len( ) ) ,
2370- ) ,
2371- infer_replacements,
2372- Applicability :: MachineApplicable ,
2373- ) ;
2374- }
2375-
2376- self . set_tainted_by_errors ( diag. emit ( ) ) ;
2377- }
2378-
23792306 // Find any late-bound regions declared in return type that do
23802307 // not appear in the arguments. These are not well-formed.
23812308 //
@@ -2405,7 +2332,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24052332 /// corresponding function in the trait that the impl implements, if it exists.
24062333 /// If arg_idx is Some, then it corresponds to an input type index, otherwise it
24072334 /// corresponds to the return type.
2408- fn suggest_trait_fn_ty_for_impl_fn_infer (
2335+ pub ( super ) fn suggest_trait_fn_ty_for_impl_fn_infer (
24092336 & self ,
24102337 fn_hir_id : HirId ,
24112338 arg_idx : Option < usize > ,
0 commit comments