@@ -3,10 +3,9 @@ use rustc_ast::ptr::P;
33use rustc_ast:: visit:: AssocCtxt ;
44use rustc_ast:: * ;
55use rustc_errors:: ErrorGuaranteed ;
6- use rustc_hir as hir;
7- use rustc_hir:: PredicateOrigin ;
86use rustc_hir:: def:: { DefKind , Res } ;
97use rustc_hir:: def_id:: { CRATE_DEF_ID , LocalDefId } ;
8+ use rustc_hir:: { self as hir, HirId , PredicateOrigin } ;
109use rustc_index:: { IndexSlice , IndexVec } ;
1110use rustc_middle:: span_bug;
1211use rustc_middle:: ty:: { ResolverAstLowering , TyCtxt } ;
@@ -209,6 +208,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
209208 generics,
210209 body,
211210 contract,
211+ define_opaque,
212212 ..
213213 } ) => {
214214 self . with_new_scopes ( * fn_sig_span, |this| {
@@ -237,6 +237,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
237237 header : this. lower_fn_header ( * header, hir:: Safety :: Safe , attrs) ,
238238 span : this. lower_span ( * fn_sig_span) ,
239239 } ;
240+ this. lower_define_opaque ( hir_id, & define_opaque) ;
240241 hir:: ItemKind :: Fn { sig, generics, body : body_id, has_body : body. is_some ( ) }
241242 } )
242243 }
@@ -779,7 +780,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
779780 ) ;
780781 ( generics, kind, expr. is_some ( ) )
781782 }
782- AssocItemKind :: Fn ( box Fn { sig, generics, body : None , .. } ) => {
783+ AssocItemKind :: Fn ( box Fn { sig, generics, body : None , define_opaque , .. } ) => {
783784 // FIXME(contracts): Deny contract here since it won't apply to
784785 // any impl method or callees.
785786 let names = self . lower_fn_params_to_names ( & sig. decl ) ;
@@ -791,9 +792,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
791792 sig. header . coroutine_kind ,
792793 attrs,
793794 ) ;
795+ if define_opaque. is_some ( ) {
796+ self . dcx ( ) . span_err (
797+ i. span ,
798+ "only trait methods with default bodies can define opaque types" ,
799+ ) ;
800+ }
794801 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
795802 }
796- AssocItemKind :: Fn ( box Fn { sig, generics, body : Some ( body) , contract, .. } ) => {
803+ AssocItemKind :: Fn ( box Fn {
804+ sig,
805+ generics,
806+ body : Some ( body) ,
807+ contract,
808+ define_opaque,
809+ ..
810+ } ) => {
797811 let body_id = self . lower_maybe_coroutine_body (
798812 sig. span ,
799813 i. span ,
@@ -812,6 +826,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
812826 sig. header . coroutine_kind ,
813827 attrs,
814828 ) ;
829+ self . lower_define_opaque ( hir_id, & define_opaque) ;
815830 ( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
816831 }
817832 AssocItemKind :: Type ( box TyAlias { generics, where_clauses, bounds, ty, .. } ) => {
@@ -911,7 +926,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
911926 hir:: ImplItemKind :: Const ( ty, body)
912927 } ,
913928 ) ,
914- AssocItemKind :: Fn ( box Fn { sig, generics, body, contract, .. } ) => {
929+ AssocItemKind :: Fn ( box Fn { sig, generics, body, contract, define_opaque , .. } ) => {
915930 let body_id = self . lower_maybe_coroutine_body (
916931 sig. span ,
917932 i. span ,
@@ -930,6 +945,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
930945 sig. header . coroutine_kind ,
931946 attrs,
932947 ) ;
948+ self . lower_define_opaque ( hir_id, & define_opaque) ;
933949
934950 ( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
935951 }
@@ -1657,6 +1673,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
16571673 ( lowered_generics, res)
16581674 }
16591675
1676+ pub ( super ) fn lower_define_opaque (
1677+ & mut self ,
1678+ hir_id : HirId ,
1679+ define_opaque : & Option < ThinVec < ( NodeId , Path ) > > ,
1680+ ) {
1681+ assert_eq ! ( self . define_opaque, None ) ;
1682+ assert ! ( hir_id. is_owner( ) ) ;
1683+ let Some ( define_opaque) = define_opaque. as_ref ( ) else {
1684+ return ;
1685+ } ;
1686+ let define_opaque = define_opaque
1687+ . iter ( )
1688+ // TODO: error reporting for non-local items being mentioned and tests that go through these code paths
1689+ . map ( |( id, _path) | {
1690+ self . resolver
1691+ . get_partial_res ( * id)
1692+ . unwrap ( )
1693+ . expect_full_res ( )
1694+ . def_id ( )
1695+ . expect_local ( )
1696+ } ) ;
1697+ let define_opaque = self . arena . alloc_from_iter ( define_opaque) ;
1698+ self . define_opaque = Some ( define_opaque) ;
1699+ }
1700+
16601701 pub ( super ) fn lower_generic_bound_predicate (
16611702 & mut self ,
16621703 ident : Ident ,
0 commit comments