@@ -3,6 +3,7 @@ use super::compare_method::check_type_bounds;
33use super :: compare_method:: { compare_const_impl, compare_impl_method, compare_ty_impl} ;
44use super :: * ;
55
6+ use hir:: OpaqueTyOrigin ;
67use rustc_attr as attr;
78use rustc_errors:: { Applicability , ErrorGuaranteed } ;
89use rustc_hir as hir;
@@ -12,8 +13,9 @@ use rustc_hir::lang_items::LangItem;
1213use rustc_hir:: { def:: Res , ItemKind , Node , PathSegment } ;
1314use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
1415use rustc_infer:: infer:: { RegionVariableOrigin , TyCtxtInferExt } ;
16+ use rustc_infer:: traits:: ObligationCause ;
1517use rustc_middle:: hir:: nested_filter;
16- use rustc_middle:: ty:: fold:: TypeFoldable ;
18+ use rustc_middle:: ty:: fold:: { BottomUpFolder , TypeFoldable } ;
1719use rustc_middle:: ty:: layout:: { LayoutError , MAX_SIMD_LANES } ;
1820use rustc_middle:: ty:: subst:: GenericArgKind ;
1921use rustc_middle:: ty:: util:: { Discr , IntTypeExt } ;
@@ -95,7 +97,46 @@ pub(super) fn check_fn<'a, 'tcx>(
9597
9698 let declared_ret_ty = fn_sig. output ( ) ;
9799
98- fcx. ret_coercion = Some ( RefCell :: new ( CoerceMany :: new ( declared_ret_ty) ) ) ;
100+ let ret_ty = declared_ret_ty. fold_with ( & mut BottomUpFolder {
101+ tcx : fcx. tcx ,
102+ ty_op : |ty| match * ty. kind ( ) {
103+ ty:: Opaque ( def_id, substs) => {
104+ let span = tcx. def_span ( def_id) ;
105+ if let Some ( origin @ OpaqueTyOrigin :: FnReturn ( _) ) =
106+ fcx. infcx . opaque_type_origin ( def_id, span)
107+ {
108+ let hidden_ty = fcx. infcx . next_ty_var ( TypeVariableOrigin {
109+ kind : TypeVariableOriginKind :: MiscVariable ,
110+ span : span,
111+ } ) ;
112+
113+ let cause = ObligationCause :: misc ( span, body. value . hir_id ) ;
114+ match fcx. infcx . register_hidden_type (
115+ ty:: OpaqueTypeKey { def_id, substs } ,
116+ cause. clone ( ) ,
117+ param_env,
118+ hidden_ty,
119+ origin,
120+ ) {
121+ Ok ( infer_ok) => {
122+ fcx. register_infer_ok_obligations ( infer_ok) ;
123+ hidden_ty
124+ }
125+ Err ( err) => {
126+ fcx. report_mismatched_types ( & cause, ty, hidden_ty, err) . emit ( ) ;
127+ tcx. ty_error ( )
128+ }
129+ }
130+ } else {
131+ ty
132+ }
133+ }
134+ _ => ty,
135+ } ,
136+ lt_op : |lt| lt,
137+ ct_op : |ct| ct,
138+ } ) ;
139+ fcx. ret_coercion = Some ( RefCell :: new ( CoerceMany :: new ( ret_ty) ) ) ;
99140 fcx. ret_type_span = Some ( decl. output . span ( ) ) ;
100141
101142 let span = body. value . span ;
0 commit comments