@@ -30,7 +30,7 @@ use rustc_middle::query::Providers;
3030use rustc_middle:: ty:: util:: { Discr , IntTypeExt } ;
3131use rustc_middle:: ty:: { self , AdtKind , Const , IsSuggestable , ToPredicate , Ty , TyCtxt } ;
3232use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
33- use rustc_span:: Span ;
33+ use rustc_span:: { Span , DUMMY_SP } ;
3434use rustc_target:: abi:: FieldIdx ;
3535use rustc_target:: spec:: abi;
3636use rustc_trait_selection:: infer:: InferCtxtExt ;
@@ -1383,7 +1383,9 @@ fn infer_return_ty_for_fn_sig<'tcx>(
13831383 Applicability :: MachineApplicable ,
13841384 ) ;
13851385 should_recover = true ;
1386- } else if let Some ( sugg) = suggest_impl_trait ( tcx, ret_ty, ty. span , def_id) {
1386+ } else if let Some ( sugg) =
1387+ suggest_impl_trait ( & tcx. infer_ctxt ( ) . build ( ) , tcx. param_env ( def_id) , ret_ty)
1388+ {
13871389 diag. span_suggestion (
13881390 ty. span ,
13891391 "replace with an appropriate return type" ,
@@ -1426,11 +1428,10 @@ fn infer_return_ty_for_fn_sig<'tcx>(
14261428 }
14271429}
14281430
1429- fn suggest_impl_trait < ' tcx > (
1430- tcx : TyCtxt < ' tcx > ,
1431+ pub fn suggest_impl_trait < ' tcx > (
1432+ infcx : & InferCtxt < ' tcx > ,
1433+ param_env : ty:: ParamEnv < ' tcx > ,
14311434 ret_ty : Ty < ' tcx > ,
1432- span : Span ,
1433- def_id : LocalDefId ,
14341435) -> Option < String > {
14351436 let format_as_assoc: fn ( _, _, _, _, _) -> _ =
14361437 |tcx : TyCtxt < ' tcx > ,
@@ -1464,24 +1465,28 @@ fn suggest_impl_trait<'tcx>(
14641465
14651466 for ( trait_def_id, assoc_item_def_id, formatter) in [
14661467 (
1467- tcx. get_diagnostic_item ( sym:: Iterator ) ,
1468- tcx. get_diagnostic_item ( sym:: IteratorItem ) ,
1468+ infcx . tcx . get_diagnostic_item ( sym:: Iterator ) ,
1469+ infcx . tcx . get_diagnostic_item ( sym:: IteratorItem ) ,
14691470 format_as_assoc,
14701471 ) ,
14711472 (
1472- tcx. lang_items ( ) . future_trait ( ) ,
1473- tcx. get_diagnostic_item ( sym:: FutureOutput ) ,
1473+ infcx . tcx . lang_items ( ) . future_trait ( ) ,
1474+ infcx . tcx . get_diagnostic_item ( sym:: FutureOutput ) ,
14741475 format_as_assoc,
14751476 ) ,
1476- ( tcx. lang_items ( ) . fn_trait ( ) , tcx. lang_items ( ) . fn_once_output ( ) , format_as_parenthesized) ,
14771477 (
1478- tcx. lang_items ( ) . fn_mut_trait ( ) ,
1479- tcx. lang_items ( ) . fn_once_output ( ) ,
1478+ infcx. tcx . lang_items ( ) . fn_trait ( ) ,
1479+ infcx. tcx . lang_items ( ) . fn_once_output ( ) ,
1480+ format_as_parenthesized,
1481+ ) ,
1482+ (
1483+ infcx. tcx . lang_items ( ) . fn_mut_trait ( ) ,
1484+ infcx. tcx . lang_items ( ) . fn_once_output ( ) ,
14801485 format_as_parenthesized,
14811486 ) ,
14821487 (
1483- tcx. lang_items ( ) . fn_once_trait ( ) ,
1484- tcx. lang_items ( ) . fn_once_output ( ) ,
1488+ infcx . tcx . lang_items ( ) . fn_once_trait ( ) ,
1489+ infcx . tcx . lang_items ( ) . fn_once_output ( ) ,
14851490 format_as_parenthesized,
14861491 ) ,
14871492 ] {
@@ -1491,36 +1496,45 @@ fn suggest_impl_trait<'tcx>(
14911496 let Some ( assoc_item_def_id) = assoc_item_def_id else {
14921497 continue ;
14931498 } ;
1494- if tcx. def_kind ( assoc_item_def_id) != DefKind :: AssocTy {
1499+ if infcx . tcx . def_kind ( assoc_item_def_id) != DefKind :: AssocTy {
14951500 continue ;
14961501 }
1497- let param_env = tcx. param_env ( def_id) ;
1498- let infcx = tcx. infer_ctxt ( ) . build ( ) ;
1499- let args = ty:: GenericArgs :: for_item ( tcx, trait_def_id, |param, _| {
1500- if param. index == 0 { ret_ty. into ( ) } else { infcx. var_for_def ( span, param) }
1502+ let sugg = infcx. probe ( |_| {
1503+ let args = ty:: GenericArgs :: for_item ( infcx. tcx , trait_def_id, |param, _| {
1504+ if param. index == 0 { ret_ty. into ( ) } else { infcx. var_for_def ( DUMMY_SP , param) }
1505+ } ) ;
1506+ if !infcx
1507+ . type_implements_trait ( trait_def_id, args, param_env)
1508+ . must_apply_modulo_regions ( )
1509+ {
1510+ return None ;
1511+ }
1512+ let ocx = ObligationCtxt :: new ( & infcx) ;
1513+ let item_ty = ocx. normalize (
1514+ & ObligationCause :: dummy ( ) ,
1515+ param_env,
1516+ Ty :: new_projection ( infcx. tcx , assoc_item_def_id, args) ,
1517+ ) ;
1518+ // FIXME(compiler-errors): We may benefit from resolving regions here.
1519+ if ocx. select_where_possible ( ) . is_empty ( )
1520+ && let item_ty = infcx. resolve_vars_if_possible ( item_ty)
1521+ && let Some ( item_ty) = item_ty. make_suggestable ( infcx. tcx , false , None )
1522+ && let Some ( sugg) = formatter (
1523+ infcx. tcx ,
1524+ infcx. resolve_vars_if_possible ( args) ,
1525+ trait_def_id,
1526+ assoc_item_def_id,
1527+ item_ty,
1528+ )
1529+ {
1530+ return Some ( sugg) ;
1531+ }
1532+
1533+ None
15011534 } ) ;
1502- if !infcx. type_implements_trait ( trait_def_id, args, param_env) . must_apply_modulo_regions ( ) {
1503- continue ;
1504- }
1505- let ocx = ObligationCtxt :: new ( & infcx) ;
1506- let item_ty = ocx. normalize (
1507- & ObligationCause :: misc ( span, def_id) ,
1508- param_env,
1509- Ty :: new_projection ( tcx, assoc_item_def_id, args) ,
1510- ) ;
1511- // FIXME(compiler-errors): We may benefit from resolving regions here.
1512- if ocx. select_where_possible ( ) . is_empty ( )
1513- && let item_ty = infcx. resolve_vars_if_possible ( item_ty)
1514- && let Some ( item_ty) = item_ty. make_suggestable ( tcx, false , None )
1515- && let Some ( sugg) = formatter (
1516- tcx,
1517- infcx. resolve_vars_if_possible ( args) ,
1518- trait_def_id,
1519- assoc_item_def_id,
1520- item_ty,
1521- )
1522- {
1523- return Some ( sugg) ;
1535+
1536+ if sugg. is_some ( ) {
1537+ return sugg;
15241538 }
15251539 }
15261540 None
0 commit comments